Java 正则表达式-捕获组混淆

Java 正则表达式-捕获组混淆,java,regex,Java,Regex,我正在阅读关于正则表达式的Oracle教程。我正在谈论这个话题。虽然参考文献很好,但除了括号代表一个组外,我发现理解这个主题有很多困难。以下是我的困惑 在表达式中计算组的意义是什么 什么是非捕获组 用例子详细说明会很好 目前还没有合适的例子,但我假设有人可能需要知道正则表达式中的子匹配数 组0始终是整个基本匹配。我假设groupCount()只是让您知道在表达式中指定了多少捕获组 非捕获组(?:)将用于不捕获组。例如,如果您需要测试字符串是否包含多个单词中的一个,并且不想在新组中捕获该单词:(?

我正在阅读关于正则表达式的Oracle教程。我正在谈论这个话题。虽然参考文献很好,但除了括号代表一个组外,我发现理解这个主题有很多困难。以下是我的困惑

  • 在表达式中计算组的意义是什么
  • 什么是非捕获组
  • 用例子详细说明会很好

  • 目前还没有合适的例子,但我假设有人可能需要知道正则表达式中的子匹配数
  • 组0始终是整个基本匹配。我假设
    groupCount()
    只是让您知道在表达式中指定了多少捕获组
  • 非捕获组
    (?:)
    将用于不捕获组。例如,如果您需要测试字符串是否包含多个单词中的一个,并且不想在新组中捕获该单词:
    (?:hello | hi here)world
    !==<代码>你好|你好,世界。第一个匹配“hello world”或“hi there world”,但第二个匹配“hello”或“hi there world”
  • 它们可以作为许多有力理由的一部分,例如测试一个数字是素数还是复合数或者您可以简单地进行测试以确保搜索参数不会重复,即
    ^(\d)(?!.*\1)\d+$
    将确保字符串中的第一个数字是唯一的
  • 人们通常不计算组数,只知道哪个组有哪个数字。例如,
    ([abc])([def](\d+)
    有三个组,因此我知道将它们称为
    \1
    \2
    \3
    。请注意,组3位于组2中。它们从左边开始编号
  • 当使用正则表达式搜索字符串中的内容时,与确保整个字符串与主题匹配时的匹配不同,组0将只提供匹配的字符串,而不是之前或之后的内容。想象一下,如果你在你的整个正则表达式周围放一对括号。它不是总数的一部分,因为它不是一个真正的群体
  • 组可以用于捕获以外的其他用途。例如,
    (foo | bar)
    将匹配
    “foo”
    “bar”
    。如果您对组的内容不感兴趣,可以将其设置为非捕获(例如:
    (?:foo | bar)
    (因方言而异)),以避免“用完”分配给组的数字。但你不必,只是有时候很方便
  • 假设我想找到一个以相同字母开头和结尾的单词:
    \b([a-z])[a-z]*\1\b
    那么
    \1
    将与第一组捕获的内容相同。当然,它可以用于更强大的东西,但我想你会明白的
  • (提出相关的例子当然是最难的部分。)

    编辑:我回答的问题是:

  • 在表达式中计算组的意义是什么
  • 有一个特殊的组,称为group-0,它表示整个表达式。groupCount()方法不会报告该错误。为什么呢
  • 我不明白什么是非捕获组
  • 为什么我们需要回信?反向引用的意义是什么

  • 假设您有一个字符串,
    abcabc
    ,您想知道字符串的第一部分是否与第二部分匹配。您可以通过使用捕获组和反向引用使用单个正则表达式来实现这一点。下面是我将使用的正则表达式:

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


    反向引用的另一个用途是替换。如果
    {
    }
    中的文本仅为数字,则表示要将所有
    {…}
    替换为
    […]
    。您可以使用正则表达式轻松地通过捕获组和反向引用来实现这一点

    {(\d+)}
    
    并将其替换为
    [\1]

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


    非捕获组之所以存在,是因为组通常比仅捕获组有更多的用途。正则表达式
    (xyz)+
    匹配一个字符串,该字符串完全由重复的组
    xyz
    组成,例如
    xyzxyz
    。需要一个组,因为
    xyz+
    只匹配
    xy
    ,然后重复
    z
    ,即
    xyzzzz
    。使用捕获组的问题是,与非捕获组相比,它们的效率稍低,并且占用索引。如果你有一个复杂的正则表达式,其中有很多组,但是你只需要在中间某个地方引用一个,那么引用“<代码> 1”/>代码就更好了,而不是尝试将所有组都计算成你想要的。
    我希望这有帮助

    @benz说我有一个正则表达式,其中包含许多组,我想使用这些组的内容。我让它们捕获组,这样我就可以使用它们的内容(在带有反向引用的正则表达式中(
    \1
    等),或者在我使用的任何正则表达式库中(例如
    match.GetGroup(1)
    )。那么假设我有一个我想去的地方