What do ^ and $ mean in a regular expression? - java

What is the difference between "\\w+#\\w+[.]\\w+" and "^\\w+#\\w+[.]\\w+$"? I have tried to google for it but no luck.

^ means "Match the start of the string" (more exactly, the position before the first character in the string, so it does not match an actual character).
$ means "Match the end of the string" (the position after the last character in the string).
Both are called anchors and ensure that the entire string is matched instead of just a substring.
So in your example, the first regex will report a match on email#address.com.uk, but the matched text will be email#address.com, probably not what you expected. The second regex will simply fail.
Be careful, as some regex implementations implicitly anchor the regex at the start/end of the string (for example Java's .matches(), if you're using that).
If the multiline option is set (using the (?m) flag, for example, or by doing Pattern.compile("^\\w+#\\w+[.]\\w+$", Pattern.MULTILINE)), then ^ and $ also match at the start and end of a line.

Try the Javadoc:
http://download.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html
^ and $ match the beginnings/endings of a line (without consuming them)

Related

Regex string validation

Trying to write some regex to validate a string, where null and empty strings are not allowed, but characters + new line should be allowed. The string I'm trying to validate is as follows:
First line \n
Second line \n
This is as far as i got:
^(?!\s*$).+
This fails my validation because of the new line. Any ideas? I should add, i cannot use awk.
Code
The following regex matches the entire line.
See regex in use here
^[^\r\n]*?\S.*$
The following regexes do the same as above except they're used for validation purposes only (they don't match the whole line, instead they simply ensures it's properly formed). The benefit of using these regexes over the one above is the number of steps (performance). In the regex101 links below they show as 28 steps as opposed to 34 for the pattern above.
See regex in use here
^[^\r\n]*?\S
See regex in use here
^.*?\S
Results
Input
First line \n
Second line \n
s
Output
Matches only
First line \n
Second line \n
s
Explanation
^ Assert position at the start of the line
[^\r\n]*? Match any character not present in the set (any character except the carriage return or line-feed characters) any number of times, but as few as possible (making this lazy increases performance - less steps)
\S Match any non-whitespace character
.* Match any character (excludes newline characters) any number of times
$ Assert position at the end of the line
Try this pattern:
([\S ]*(\n)*)*

How to Java Regex to match everything but specified pattern

I am trying to match everything but garbage values in the entire string.The pattern I am trying to use is:
^.*(?!\w|\s|-|\.|[#:,]).*$
I have been testing the pattern on regexPlanet and this seems to be matching the entire string.The input string I was using was:
Vamsi///#k03#g!!!l.com 123**5
How can I get it to only match everything but the pattern,I would like to replace any string that matches with an empty space or a special charecter of my choice.
The pattern, as written, is supposed to match the whole string.
^ - start of string.
.* - zero or more of any character.
(?!\w|\s|-|\.|[#:,]) - negative look-ahead for some characters.
.* - zero or more of any character.
$ - end of string.
If you only want to match characters which aren't one of the supplied characters, try simply:
[^-\w\s.#:,]
[^...] is a negated character class, it will match any characters not supplied in the brackets. See this for more information.
Test.

Finding a simple pattern in a string unless escaped

I have some code that looks for a simple bold markup
private Pattern bold = Pattern.compile("\\*[^\\*]*\\*")
If someone uses: this my *bolded* text - my pattern would find "bolded"
I now need a way to use * not in the context of bolding. So I'd like to allow escaping.
E.g. this my \*non-bolded\* text - should not find any pattern.
Is there a simple way I can change my Regex to achieve this?
You need a negative lookbehind here:
(?<!\\)\*[^*]+(?<!\\)\*
In a Java string, this gives (backslash galore):
"(?<!\\\\)\\*[^*]+(?<!\\\\)\\*"
Note: the star (*) has no special meaning within a character class, therefore there is no need to escape it
Note 2: (?<!...) is a negative lookbehind; it is an anchor, which means it finds a position but consumes no text. Literally, it can be translated as: "find a position where there is no preceding text matching regex ...". Other anchors are:
^: find a position where there is no available input before (ie, can only match at the beginning of the input);
$: find a position where there is no available input after (ie, can only match at the end of the input);
(?=...): find a position where the following text matches regex ... (this is called a positive lookahead);
(?!...): find a position where the following text does not match regex ... (this is called a negative lookahead);
(?<=...): find a position where the preceding text matches regex ... (this is a positive lookbehind);
\<: find a position where the preceding input is either nothing or a character which is not a word character, and the following character is a word character (implementation dependent);
\>: find a position where the following input is either nothing or a character which is not a word character, and the preceding character is a word character (implementation dependent);
\b: either \< or \>.
Note 3: Javascript regexes do not support lookbehinds; neither do they support \< or \>. More information here.
Note 4: with some regex engines, it is possible to alter the meaning of ^ and $ to match positions at the beginning and end of each line instead; in Java, that is Pattern.MULTILINE; in Perl-like regex engines, that is /m.
This negative lookbehind based regex should work for you:
(?<!\\)\*[^*]+\*(?<!\\)
Live Demo: http://www.rubular.com/r/sobKUrkTjP
When translated to Java it will become:
(?<!\\\\)\\*[^*]+\\*(?<!\\\\)
I think the two answers until now are very interesting, but not completely correct. They don't work when a bolded text has escaped asterisk inside (I assume this is almost the main reason to escape asterisks).
For example:
My *bold \*text* here, another *bold*, more \* and *here\* and
\* end* more text
Should find three groups:
*bold \*text*
*bold*
*here\* and \* end*
With a little modification, we can do that, with this regular expression:
(?<!\\)\*([^*\\]|\\\*)+\*
can be tested here:
http://www.rubular.com/r/Jeml02HHYJ
Of course, in Java some more escaping is needed:
(?<!\\\\)\\*([^*\\\\]|\\\\\\*)+\\*

regular expression to match one or more of char a or just one of char b

I am taking user input through UI, and I have to validate it. Input text should obey the following ondition
It should either end with one or more
white space characters OR with just
single '='
I can use
".*[\s=]+"
but it matches multiple '=' also which I don't want to.
Please help.
You can use alternation:
(\s+|=)$
This expression means match one or more whitespace character or one equals, at the end of the string. The $ is an anchor which matches the end of the string (as you mentioned you're looking for characters at the end of the string).
(As tchrist correctly pointed out in the comments, $ matches the end of line instead of end of string when in multiline mode. If this is true in your case, and you are indeed looking for the end of the string instead of the end of the line, you can use \Z instead, which matches the end of the string regardless of multiline mode.)
If you want to ensure that there is only one = at the end, you can use a lookaround (in this case, a negative lookbehind, specifically). A lookaround is a zero-width assertion which tells the regex engine that the assertion must pass for the pattern to match, but it does not consume any characters.
(\s+|(?<!=)=)$
In this case, (?<!=) tells the regex engine, the character before the current position cannot be an =. When put into the expression, (?<!=)= means that the = will only match if the previous character is not also a =.
Begin string
Anything not "=" ( to avoid the double "==")
One or more blank spaces OR one "="
End of string
^([^=]*[\s+|=])$
Should work :-)
Try this expression:
".*(\\s+|=)"

What is the pattern for empty string?

I need to validate input: valid variants are either number or empty string. What is the correspondent regular expression?
String pattern = "\d+|<what shoudl be here?>";
UPD: dont suggest "\d*" please, I'm just curious how to tell "empty string" in regexp.
In this particular case, ^\d*$ would work, but generally speaking, to match pattern or an empty string, you can use:
^$|pattern
Explanation
^ and $ are the beginning and end of the string anchors respectively.
| is used to denote alternates, e.g. this|that.
References
regular-expressions.info/Anchors and Alternation
Related questions
Regular expression which matches a pattern, or is an empty string
Note on multiline mode
In the so-called multiline mode (Pattern.MULTILINE/(?m) in Java), the ^ and $ match the beginning and end of the line instead. The anchors for the beginning and end of the string are now \A and \Z respectively.
If you're in multiline mode, then the empty string is matched by \A\Z instead. ^$ would match an empty line within the string.
Examples
Here are some examples to illustrate the above points:
String numbers = "012345";
System.out.println(numbers.replaceAll(".", "<$0>"));
// <0><1><2><3><4><5>
System.out.println(numbers.replaceAll("^.", "<$0>"));
// <0>12345
System.out.println(numbers.replaceAll(".$", "<$0>"));
// 01234<5>
numbers = "012\n345\n678";
System.out.println(numbers.replaceAll("^.", "<$0>"));
// <0>12
// 345
// 678
System.out.println(numbers.replaceAll("(?m)^.", "<$0>"));
// <0>12
// <3>45
// <6>78
System.out.println(numbers.replaceAll("(?m).\\Z", "<$0>"));
// 012
// 345
// 67<8>
Note on Java matches
In Java, matches attempts to match a pattern against the entire string.
This is true for String.matches, Pattern.matches and Matcher.matches.
This means that sometimes, anchors can be omitted for Java matches when they're otherwise necessary for other flavors and/or other Java regex methods.
Related questions
Regex doesn't work in String.matches()
/^\d*$/
Matches 0 or more digits with nothing before or after.
Explanation:
The '^' means start of line. '$' means end of line. '*' matches 0 or more occurences. So the pattern matches an entire line with 0 or more digits.
To explicitly match the empty string, use \A\Z.
You can also often see ^$ which works fine unless the option is set to allow the ^ and $ anchors to match not only at the start or end of the string but also at the start/end of each line. If your input can never contain newlines, then of course ^$ is perfectly OK.
Some regex flavors don't support \A and \Z anchors (especially JavaScript).
If you want to allow "empty" as in "nothing or only whitespace", then go for \A\s*\Z or ^\s*$.
Just as a funny solution, you can do:
\d+|\d{0}
A digit, zero times. Yes, it does work.
There shouldn't be anything wrong with just "\d+|"
One of the way to view at the set of regular language as the closure of the below things:
Special < EMPTY_STRING > is the regular language
Any symbol from alphaphet is the valid regular language
Any concatentation and union of two valid regexps is the regular language
Any union of two valid regular language is the regular language
Any transitive closure of the regexp is the regular language
Concreate regular language is concrete element of this closure.
I didn't find empty symbol in POSIX standard to express regular language idea from step (1).
But it is exist extra thing like question mark there which is by posix definition is the following:
(regexp|< EMPTY_STRING >)
So you can do in the following manner for bash, perl, and python:
echo 9023 | grep -E "(1|90)?23"
perl -e "print 'PASS' if (qq(23) =~ /(1|90)?23/)"
python -c "import re; print bool(re.match('^(1|90)?23$', '23'))"
To make any pattern that matches an entire string optional, i.e. allow a pattern match an empty string, use an optional group:
^(pattern)?$
^^ ^^^
See the regex demo
If the regex engine allows (as in Java), prefer a non-capturing group since its main purpose is to only group subpatterns, not keep the subvalues captured:
^(?:pattern)?$
The ^ will match the start of a string (or \A can be used in many flavors for this), $ will match the end of string (or \z can be used to match the very end in many flavors, and Java, too), and the (....)? will match 1 or 0 (due to the ? quantifier) sequences of the subpatterns inside parentheses.
A Java usage note: when used in matches(), the initial ^ and trailing $ can be omitted and you can use
String pattern = "(?:\d+)?";

Categories

Resources