问题
Please take a look at the following code:
public static void main(String[] args) {
String s = "a < b > c > d";
String regex = "(\\w\\s*[<>]\\s*\\w)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
int i = 0;
while (m.find()) System.out.println(m.group(i++));
}
The output of the above program is: a < b, c > d
But I actually expect a < b, b > c, c > d
.
Anything wrong with my regexp here?
回答1:
Try this.
String s = "a < b > c > d";
String regex = "(?=(\\w{1}\\s{1}[<>]{1}\\s{1}\\w{1})).";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group(1));
}
Updated(Based on green's solution):
String s = " something.js > /some/path/to/x19-v1.0.js < y < z < a > b > c > d";
String regex = "(?=[\\s,;]+|(?<![\\w\\/\\-\\.])([\\w\\/\\-\\.]+\\s*[<>]\\s*[\\w\\/\\-\\.]+))";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while (m.find()) {
String d = m.group(1);
if(d != null) {
System.out.println(d);
}
}
回答2:
You're right in your thinking that b > c matches the regex because it does.
But when you call Matcher::find(), it returns the next substring of the input which matches the regex and is disjoint from previous find() matches. Since "b > c" begins with the 'b' which was part of the "a > b" match returned by the previous invocation, it won't be returned by find().
回答3:
Based on John's solution and adding some boundary matchers, this works finally.
String s = " something.js > /some/path/to/x19-v1.0.js < y < z < a > b > c > d";
String regex = "(?=[\\s,;]+([\\w\\/\\-\\.]+\\s*[<>]\\s*[\\w\\/\\-\\.]+)[\\s,;$]*).";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group(1));
}
来源:https://stackoverflow.com/questions/5508965/overlapping-group-capturing