I'm working on a new Java project and therefore im reading the already existing code. On a very important part of the code if开发者_运维百科 found the following regex expression and i can't really tell what they are doing. Anybody can explain in plain english what they do??
1)
[^,]*|.+(,).+
2)
(\()?\d+(?(1)\))
Next time you need a regex explained, you can use the following explain.pl
service from Rick Measham:
Regex: [^,]*|.+(,).+
NODE EXPLANATION
--------------------------------------------------------------------------------
[^,]* any character except: ',' (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
| OR
--------------------------------------------------------------------------------
.+ any character except \n (1 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
( group and capture to \1:
--------------------------------------------------------------------------------
, ','
--------------------------------------------------------------------------------
) end of \1
--------------------------------------------------------------------------------
.+ any character except \n (1 or more times
(matching the most amount possible))
Regex: (\()?\d+(?(1)\))
NODE EXPLANATION
--------------------------------------------------------------------------------
( group and capture to \1 (optional
(matching the most amount possible)):
--------------------------------------------------------------------------------
\( '('
--------------------------------------------------------------------------------
)? end of \1 (NOTE: because you're using a
quantifier on this capture, only the LAST
repetition of the captured pattern will be
stored in \1)
--------------------------------------------------------------------------------
\d+ digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
(?(1) if back-reference \1 matched, then:
--------------------------------------------------------------------------------
\) ')'
--------------------------------------------------------------------------------
| else:
--------------------------------------------------------------------------------
succeed
--------------------------------------------------------------------------------
) end of conditional on \1
Links
- http://rick.measham.id.au/paste/explain.pl
Note on conditionals
JAVA DOES NOT SUPPORT CONDITIONALS! An unconditionalized regex for the second pattern would be something like:
\d+|\(\d+\)
i.e. a non-zero repetition of digits, with or without surrounding parentheses.
Links
- regular-expressions.info/If-then-else conditionals
Conditionals are supported by the JGsoft engine, Perl, PCRE and the .NET framework.
The patterns in depth
Here's a test harness for the first pattern
import java.util.regex.*;
//...
Pattern p = Pattern.compile("[^,]*|.+(,).+");
String[] tests = {
"", // [] is a match with no commas
"abc", // [abc] is a match with no commas
",abc", // [,abc] is not a match
"abc,", // [abc,] is not a match
"ab,c", // [ab,c] is a match with separating comma
"ab,c,", // [ab,c,] is a match with separating comma
",", // [,] is not a match
",,", // [,,] is not a match
",,,", // [,,,] is a match with separating comma
};
for (String test : tests) {
Matcher m = p.matcher(test);
System.out.format("[%s] is %s %n", test,
!m.matches() ? "not a match"
: m.group(1) != null
? "a match with separating comma"
: "a match with no commas"
);
}
Conclusion
- To match, the string must fall into one of these two cases:
- Contains no comma (potentially an empty string)
- Contains a comma that separates two non-empty strings
- On a match,
\1
can be used to distinguish between the two cases
And here's a similar test harness for the second pattern, rewritten without using conditionals (which isn't supported by Java):
Pattern p = Pattern.compile("\\d+|(\\()\\d+\\)");
String[] tests = {
"", // [] is not a match
"0", // [0] is a match without parenthesis
"(0)", // [(0)] is a match with surrounding parenthesis
"007", // [007] is a match without parenthesis
"(007)", // [(007)] is a match with surrounding parenthesis
"(007", // [(007] is not a match
"007)", // [007)] is not a match
"-1", // [-1] is not a match
};
for (String test : tests) {
Matcher m = p.matcher(test);
System.out.format("[%s] is %s %n", test,
!m.matches() ? "not a match"
: m.group(1) != null
? "a match with surrounding parenthesis"
: "a match without parenthesis"
);
}
As previously said, this matches a non-zero number of digits, possibly surrounded by parenthesis (and \1
distinguishes between the two).
1)
[^,]* means any number of characters that are not a comma
.+(,).+ means 1 or more characters followed by a comma followed by 1 or more characters
| means either the first one or the second one
2)
(\()? means zero or one '(' note* backslash is to escape '('
\d+ means 1 or more digits
(?(1)\)) means if back-reference \1 matched, then ')' note* no else is given
Also note that parenthesis are used to capture certain parts of the regular expression, except, of course, if they are escaped with a backslash
1) Anything that doesn't starts with a comma, or anything that contains a comma in between.
2) Any number that ends with a 1, and is between parenthesis, possible closed before and opened again after the number.
精彩评论