正则表达式 - 捕捉群体混乱

时间:2014-02-10 19:32:27

标签: java regex

我正在阅读关于正则表达式的Oracle教程。我的主题是 Capturing groups 。尽管参考文献非常好,但除了括号代表一个组之外,我发现在理解该主题方面存在许多困难。这是我的困惑。

  1. 在表达式中计算组的意义是什么?
  2. 什么是非捕获组?
  3. 用例子说明会很好。

3 个答案:

答案 0 :(得分:2)

  1. 除了知道哪个组有哪个号码之外,通常不会计算组。例如。 ([abc])([def](\d+))有三个小组,因此我知道将其称为\1\2\3。请注意,第3组是内部 2.它们从左侧开始编号开始
  2. 使用正则表达式搜索来查找字符串中的内容时,与匹配相反,当您确保整个字符串与主题匹配时,组0将仅提供匹配的字符串,但不是之前或之后的东西。想象一下,如果你将围绕整个正则表达式使用一对括号。它不是总数的一部分,因为它并不是真正的群体。
  3. 群组可用于捕获以外的其他内容。例如。 (foo|bar)将与"foo" "bar"匹配。如果您对组的内容不感兴趣,可以将其设置为非捕获(例如:(?:foo|bar)(因方言而异)),以免“用尽”分配给组的号码。但你不必须,有时候这很方便。
  4. 我希望找到一个以相同字母开头和结尾的单词:\b([a-z])[a-z]*\1\b \1将与第一个捕获的组相同。当然它可以用于更强大的东西,但我认为你会明白这一点。
  5. (提出相关的例子肯定是最难的部分。)

    编辑:当问题出现时我回答:

      
        
    1. 在表达式中计算组的意义是什么?
    2.   
    3. 有一个特殊的组,称为group-0,表示整个表达式。 groupCount()方法不会报告它。那是为什么?
    4.   
    5. 我不明白什么是非捕获组?
    6.   
    7. 为什么我们需要反向引用?反向引用有什么意义?
    8.   

答案 1 :(得分:2)

假设您有一个字符串abcabc,并且您想要确定字符串的第一部分是否与第二部分匹配。您可以使用捕获组和反向引用通过单个正则表达式执行此操作。这是我要使用的正则表达式:

(.+)\1

这种方式的工作方式是.+匹配任何字符序列。因为它在括号中,所以在组中捕获\11 st捕获组的反向引用,因此它等同于捕获组捕获的文本。经过一些回溯后,捕获组匹配字符串的第一部分abc。反向引用\1现在相当于abc,因此它匹配字符串的后半部分。整个字符串现在匹配,因此确认字符串的前半部分与后半部分匹配。


反向引用的另一个用途是替换。如果{...}[...]内的文字只是数字,则假设您要将所有{替换为}。您可以使用正则表达式

轻松捕获组和反向引用
{(\d+)}

[\1]代替。

正则表达式匹配字符串{123}中的abc {123} 456,并捕获第一个捕获组中的123。后引用\1现在相当于123,因此使用{(\d+)}替换abc {123} 456中的[\1]会产生abc [123] 456


存在非捕获组的原因是因为组通常具有更多仅仅捕获的用途。正则表达式(xyz)+匹配一个字符串,该字符串完全由重复的xyz组组成,例如xyzxyzxyz。需要一个群组,因为xyz+仅匹配xy,然后重复z,即xyzzzzz。使用捕获组的问题在于,与非捕获组相比,它们的效率略低,并且它们占用索引。如果你有一个复杂的正则表达式,其中包含很多组,但你只需要在中间的某个地方引用一个正则表达式,那么引用\1而不是尝试计算所有组的数量要好得多你想要的那个。

我希望这有帮助!

答案 2 :(得分:1)

  1. 目前想不出合适的例子,但我假设某人可能需要知道RegEx中的子匹配数量。
  2. 组0始终是整个基本匹配。我假设groupCount()只是让你知道你在表达式中指定了多少个捕获组。
  3. 非捕获组(?:)将用于捕获组。防爆。如果您需要测试一个字符串是否包含多个单词中的一个并且不想在新组中捕获该单词:(?:hello|hi there) world!== hello|hi there world。第一场比赛是“hello world”或“hi there world”,但第二场比赛是“hello”或“hi there world”。
  4. 它们可以作为众多有力理由的一部分使用,例如测试数字是素数还是复数。 :)或者您可以简单地测试以确保不重复搜索参数,即。 ^(\d)(?!.*\1)\d+$将确保第一个数字在字符串中是唯一的。