1

这个正则表达式是否正确将一个句子分成 3 个标记:

  1. 括号内小写字母之前的字符
  2. 括号内的小写字母,包括括号
  3. 小写括号字母后的字符

System.out.println("This is (a) test".matches("^(.*)?\\([a-z]*\\)(.*)?$"));

字符串可能有也可能没有括号小写字母,它可能出现在句子的任何地方。如果您在我没有考虑过的用例中发现缺陷,您能否在 regex 中提供更正?

对于上面的例子。

Group1 captures This is 
Group2 captures (a)
Group3 captures  test

编辑:: 如何更改正则表达式以实现以下目标?

如果字符串有 (foo)(bar)(baz) 我如何捕获 group1= empty group2=(foo) 和 group3=empty。并三次找到上述模式,因为有 3 个括号。

4

5 回答 5

0

在蟒蛇中:

r=re.compile(r'([^()]*)(\([a-z)(]*\))([^()]*)')

r.match('abc(xx)dd').groups()
  ('abc', '(xx)', 'dd')`
r.match('abc(xx)(dd)dd').groups()
  ('abc', '(xx)(dd)', 'dd')
r.match('(abc)').groups()
  ('', '(abc)', '')
于 2013-05-14T21:49:02.973 回答
0

你的正则表达式有一点问题。

您在定义中说您有 3 个组,而实际上您的模式包含 2 个。

使用文字括号不算作一个组,所以你需要使用这样的东西:

"^(.*)?(\\([a-z]*\\))(.*)?$"

或者,如果您真的不想要括号,只想要字母,您可以更改顺序:

"^(.*)?\\(([a-z]*)\\)(.*)?$"

除此之外,它似乎没问题,但请记住,括号之间的小写字母在您的模式中不是强制性的。

于 2013-05-14T17:13:48.680 回答
0

如果您希望第一组和第三组包含括号前后的所有字符,必须确保它们排除()(您.*还将匹配包含括号的组,例如(foo)(bar)在第二个示例中)。

所以我会.*用这个替换[^\\(\\)]*

此外,如果要匹配包含第二组许多子字符串的字符串(如第二个示例中),则应该*在第二组之后。

我的结果是这样的:

^([^\\(\\)]*)?(\\([a-z]*\\))*([^\\(\\)]*)?$

这将适用于第一个示例和第二个示例,但第二组最终将仅存储找到的最后一个 - (bz)

如果您希望能够像您在第二个示例中所说的那样捕获第二组 3 次,您可以尝试使用while m.find()而不是if m.matches()( mis a Matcherobject); 并将您的正则表达式更改为:

([^\\(\\)]*)(\\([a-z]*\\))([^\\(\\)]*)

这应该是字符串中每个可能匹配的第二组 - (foo), (bar), (bz)

编辑:由于某种我无法真正解释的原因,对我来说它没有找到(foo),只有另外两个。所以我写了一段代码,尝试find()使用一个参数,明确地从某个位置开始,最后找到的组结束:

String regex = "([^\\(\\)]*)(\\([a-z]*\\))([^\\(\\)]*)";
String text = "(foo)(bar)(bz)";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(text);

for (int reg = 0; reg < text.length(); reg+=(m.end()-m.start()))
        if (m.find(reg))
            for (int group = 1; group <=m.groupCount(); group++)
                System.out.println("Group "+group+": "+m.group(group));

这有效,输出为:

Group 1: 
Group 2: (foo)
Group 3: 
Group 1: 
Group 2: (bar)
Group 3: 
Group 1: 
Group 2: (bz)
Group 3: 
于 2013-05-14T21:21:30.747 回答
0

与检查正则表达式不同,每当我编写正则表达式时,我都会编写一系列单元测试来涵盖每种情况。我建议你也这样做。使用正则表达式创建四个测试(至少)并针对字符串进行测试:

  • (a) 这是测试
  • 这是一个测验
  • 这是测试(一)
  • 这是一个测验

这应该涵盖您描述的每种情况。这比尝试手动分析每种情况的正则表达式要容易和快捷得多。

于 2013-05-14T17:08:28.773 回答
0

如果你想确保是你的下括号内的字符,你应该使用+,它代表一次或多次

[a-z]+

它的方式,This is (a) (b) test将产生

Group1 captures This is 
Group2 captures (a)
Group3 captures  (b) test

如果预计 Group2 是(b)您应该在 Group1 中使用贪婪的正则表达式

建议的测试用例:

  • empty - 真的是空的,不能有一个空的项目符号点。
  • foo(bar)baz
  • (foo)(bar)(baz)
  • (富)酒吧(巴兹)
  • foo(bar)(baz)bing
  • foo(bar)baz(bing)
  • 富(酒吧)
  • (富)酒吧
于 2013-05-14T17:09:07.157 回答