是否可以创建具有可变数量的组的正则表达式?
以此为例运行......
Pattern p = Pattern.compile("ab([cd])*ef");
Matcher m = p.matcher("abcddcef");
m.matches();
......我想要像
这样的东西m.group(1)
= "c"
m.group(2)
= "d"
m.group(3)
= "d"
m.group(4)
= "c"
。(背景:我正在解析一些数据行,其中一个“字段”正在重复。我想避免对这些字段进行matcher.find
循环。)
答案 0 :(得分:20)
根据documentation,Java正则表达式不能这样做:
与a关联的捕获输入 小组总是后续的 该群组最近匹配。如果一个 小组第二次评估 因为量化然后它 以前捕获的值,如果有的话, 如果是第二个,将被保留 评估失败。匹配字符串 “aba”反对表达式(a(b)?)+, 例如,将第二组设置为 “B”。所有捕获的输入都被丢弃 在每场比赛开始时。
(强调补充)
答案 1 :(得分:3)
Pattern p = Pattern.compile("ab(?:(c)|(d))*ef");
Matcher m = p.matcher("abcdef");
m.matches();
应该做你想做的事。
编辑:
@aioobe,我现在明白了。你希望能够做一些像语法
的事情A ::== <Foo> <Bars> <Baz>
Foo ::== "foo"
Baz ::== "baz"
Bars ::== <Bar> <Bars>
| ε
Bar ::== "A"
| "B"
并提取Bar
的所有匹配项。
不,使用java.util.regex
无法做到这一点。您可以在Bars
的匹配上递归和使用正则表达式,或者使用像ANTLR这样的解析器生成器,并将副作用附加到Bar
。
答案 2 :(得分:3)
您可以使用split将所需的字段放入数组中并循环显示。
http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#split(java.lang.String)
答案 3 :(得分:2)
我没有使用java正则表达式,但对于许多语言,答案是:否。
捕获组似乎是在解析正则表达式时创建的,并在匹配字符串时填充。表达式(a)|(b)(c)
有三个捕获组,只有当其中一个或两个可以填充时。 (a)*
只有一个组,解析器在匹配后保留组中的最后一个匹配。
答案 4 :(得分:0)
我认为回溯会抑制这种行为,并说/([\S\s])/
在其分组累积状态中对圣经这样的行为的影响。即使可以做到,输出也是不可知的,因为这些组将失去位置意义。最好在全局意义上对类似的regex做一个单独的正则表达式并将其存放到数组中。
答案 5 :(得分:0)
我刚刚遇到了类似的问题,并设法做了“可变数量的组”但是组合了一个while循环并重置了匹配器。
int i=0;
String m1=null, m2=null;
while(matcher.find(i) && (m1=matcher.group(1))!=null && (m2=matcher.group(2))!=null)
{
// do work on two found groups
i=matcher.end();
}
但这是我的问题(两次重复
Pattern pattern = Pattern.compile("(?<=^ab[cd]{0,100})[cd](?=[cd]{0,100}ef$)");
Matcher matcher = pattern.matcher("abcddcef")
int i=0;
String res=null;
while(matcher.find(i) && (res=matcher.group())!=null)
{
System.out.println(res);
i=matcher.end();
}
您无法使用*
或+
指定任意长度的重复,因为前瞻和后视必须具有可预测的长度。
答案 6 :(得分:0)
如果您遇到的匹配组的最大数量合理:
"ab([cd])?([cd])?([cd])?([cd])?([cd])?([cd])?([cd])?([cd])?ef"
此示例适用于 0 - 8 个匹配项。我承认这很丑陋,而且不是人类可读的。