这个正则表达式总是按照下面的要求工作吗?

时间:2013-05-14 17:01:09

标签: java regex

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

  1. 括号内的小写字母前的字符
  2. 括号内的小写字母,包括括号
  3. 小写括号后的字符
  4. System.out.println("This is (a) test".matches("^(.*)?\\([a-z]*\\)(.*)?$"));

    字符串可能有也可能没有带括号的小写字母,它可能出现在句子的任何地方。如果你看到我没有考虑的用例中的缺陷,你能提供正则表达式的修正吗?

    对于例如上方。

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

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

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

5 个答案:

答案 0 :(得分:0)

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

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

这应该涵盖您所描述的每个案例。这比试图分析每个案例的正则表达式更容易,更快。

答案 1 :(得分:0)

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

[a-z]+

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

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

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

建议的测试用例:

  • 空 - 真空,不能有一个空位。
  • FOO(巴)巴兹
  • (FOO)(巴)(巴兹)
  • (富)巴(巴兹)
  • FOO(巴)(巴兹)冰
  • FOO(巴)巴兹(冰)
  • FOO(巴)
  • (富)条

答案 2 :(得分:0)

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

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

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

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

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

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

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

答案 3 :(得分:0)

如果您希望第一个和第三个组包含之前的所有字符之后的,则必须确保它们排除(和{{1 (您的)也会匹配包含parantheses的组,例如第二个示例中的.*。)

所以我会用(foo)(bar)替换.*

另外,如果你想匹配包含第二组许多子串的字符串(比如你的第二个例子),你应该在第二组之后有[^\\(\\)]*

我的结果是:

*

这适用于第一个示例和第二个示例,但第二个组最终只会存储找到的最后一个示例 - ^([^\\(\\)]*)?(\\([a-z]*\\))*([^\\(\\)]*)?$

如果您希望能够像第二个示例所说的那样捕获第二组3次,则可以尝试使用(bz)代替while m.find()if m.matches()是{{} 1}} object);并且还将你的正则表达式改为:

m

这应该是字符串中每个可能匹配的第二个组 - Matcher([^\\(\\)]*)(\\([a-z]*\\))([^\\(\\)]*) (foo)

编辑: 由于某种原因,我无法解释,对我而言,它找不到(bar),只找到其他两个。所以我编写了一段代码,尝试将(bz)与参数一起使用,显式从某个位置开始,最后找到的组结束:

(foo)

这样可行,输出为:

find()

答案 4 :(得分:0)

在python中:

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)', '')