给出类似
的字符串Prefix without commas, remainder with optional suffix (optional suffix)
匹配并在一次传递中提取3个字符串的最佳Java正则表达式是什么?
对于上面的例子,3组(在引号内)将是
弦的所有3个部分都是可变长度的。 “余数”部分可能包含逗号和括号本身,可选后缀可能或不以空格开头,后跟左括号,后跟零个或多个字符,后跟右括号,后跟可选空格,后跟最终的线。
尝试类似
的内容([^,]*),(.*)(\s*\(.*\))?
仅产生第1组和第2组,将第3组放在第2组的末尾。
答案 0 :(得分:2)
([^,]*),(.*)(\s*\(.*\))?
失败的原因是正则表达式已经成功([^,]*),(.*)
,并且不需要检查(回溯)其余部分。
要使其正常工作,请按以下方式更改(可能有多个选项),这些选项可以匹配而不带最后一个括号,或者与最后一个括号匹配:
^([^,]*),(.*[^\) ]\s*$) | ([^,]*),(.*)(\s*\(.*\))\s*$
结果($1 + $3
和$2 + $4
应合并,$1
和$2
如果没有可选前缀则填充:
3: Prefix without commas
4: remainder with optional suffix
5: (optional suffix)
这里我假设您的可选后缀可以多次出现。另一种阅读问题的方法是,您希望重复中间部分,即$3
中包含$2
。你可以这样做:
^([^,]*),(.*(?:[^\) ]\s*$ | (\s*\(.*\)\s*$)))
结果:
1: Prefix without commas
2: remainder with optional suffix (optional suffix)
3: (optional suffix)
编辑:更新上面的正则表达式以允许在右括号后面的空格(这是微妙的,你需要将空格添加到负字符类),并锚定正则表达式以加速和减少回溯
答案 1 :(得分:1)
您可以使用以下正则表达式:
"^([^,]*),([^()]*)(\\s*\\(.*\\))?$"
正则表达式匹配:
^
- 字符串的开头([^,]*)
- (第1组)除,
,
- 文字,
([^()]*)
- (第2组)除(
和)
(\\s*\\(.*\\))?
- (第3组)可选组(由于?
量词意味着前一个子模式出现1或0次):
\\s*
- 0个或更多空格\\(.*\\)
- 文字(
然后尽可能多的字符,直到最后)
为止。$
- 字符串结尾(如果实际字符串可以更长,则删除,并且您正在寻找更小的子字符串)。请参阅IDEONE demo
String str = "String prefix without commas, variable length remainder with optional suffix (optional suffix)";
Pattern ptrn = Pattern.compile("^([^,]*),([^()]*)(\\s*\\(.*\\))?$");
Matcher matcher = ptrn.matcher(str);
while (matcher.find()) {
System.out.println("First group: " + matcher.group(1)
+ "\nSecond group: " + matcher.group(1)
+ (matcher.group(3) != null ?
"\nThrid group: " + matcher.group(3) : ""));
答案 2 :(得分:1)
以下正则表达式:
^([^,]*),(.*?)(?:\(([^()]*)\))?\s*$
使用组2中的延迟量词来保证如果有任何括号,组3将匹配。另一方面,第3组不允许嵌套的parens,仅在字符串的最后一组parens中强制匹配。
<强>代码:强>
String text = "String prefix without commas, variable length ())(remainde()r with )optional (suffix (optional suffix)";
Pattern regex = Pattern.compile("^([^,]*),(.*?)(?:[(]([^()]*)[)])?\\s*$");
Matcher m = regex.matcher(text);
if (m.find()) {
System.out.println("1: " + m.group(1));
System.out.println("2: " + m.group(2));
System.out.println("3: " + m.group(3));
}
<强>输出:强>
1: String prefix without commas
2: variable length ())(remainde()r with )optional (suffix
3: optional suffix