在Pattern
类中,它表示有两种类型的正则表达式:捕获和非捕获,但我不明白其中的区别。
http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#special
他们有什么不同?我何时必须使用每一个?有什么例子吗?
答案 0 :(得分:3)
考虑一种模式,您需要在一个位置检查各种事物,例如一堆不同的两个字符模式。通常使用|
交替运算符:
/(ab|cd|ef)/
也需要使用()
括号。但这些括号也可作为捕获组。也许你真的不想捕获那些char序列,只是检查它们的存在,这是非捕获组发挥作用的地方:
/(?:ab|cd|ef)/
答案 1 :(得分:2)
您可能希望分组表达式独立于捕获某些内容。例如:
abc(foo|bar)def
如果您想匹配“abdfoodef”或“abcbardef”,但没有其他变体,这是最简单的表达式。您必须使用()
将两个表达式分组才能使用|
。但这也意味着(foo|bar)
是第一个捕获组。
如果您不想要或不需要捕获,请将其写为非捕获组:
abc(?:foo|bar)def
答案 2 :(得分:1)
捕获组允许您重用部分正则表达式匹配。您可以在正则表达式中重用它,或者之后例如在替换语句中重用它:
考虑这个文本:1a2b3cdef7g9h 和这个正则表达式:([0-9] *)([a-z] *) 有两个捕获组,第一个捕获数字序列,第二个捕获数组序列。
因此,您可以使用replaceAll语句使用第一个捕获组($ 1)保留数字,或者使用第二个捕获组($ 2)保留字母。
// next line outputs : 12379
System.out.println("1a2b3cdef7g9h".replaceAll("([0-9]*)([a-z]*)", "$1"));
// next line outputs : abcdefgh
System.out.println("1a2b3cdef7g9h".replaceAll("([0-9]*)([a-z]*)", "$2"));
但是当你使用非捕获组时(例如通过添加?:它不会被捕获,并且它有时是有用的。例如:
// next line outputs : abcdefgh
// ([a-z]*) becomes the first capturing group because (?:[0-9]*) is a non-capturing group
System.out.println("1a2b3cdef7g9h".replaceAll("(?:[0-9]*)([a-z]*)", "$1"));
在http://gskinner.com/RegExr上试用 在屏幕底部,您可以看到捕获组的位置
答案 3 :(得分:1)
我想应该提一下,你也可以像这样创建命名捕获组:
(?<telephone>(?:\(\d{2}\)\s\d{4}\s\d{4}))
与(02) 9502 5697
然后您可以将其用作反向引用,如下所示:
"s/(?<telephone>(?:\(\d{2}\)\s\d{4}\s\d{4}))/\k<telephone>/g"
哪个会替换自己的匹配......但你可以用它来创造。
希望这有帮助。
答案 4 :(得分:0)
捕获/不捕获不是指整个正则表达式,而是指组,即带括号的表达式。
你想
吗?如果是,那么您将需要捕获组。
如果不是,那么您正在使用括号进行优先控制,并且可以使该组无法捕获。