分组与反向引用

用括号把字符组合起来,用分支表示“或”,再捕获一次匹配,并在同一个正则里用反向引用(backreference)再次使用它。

阅读规则:指南中的“分组:捕获与命名” →反复操练:刁钻正则 →

本课程建立在锚点与边界之上

你将学到

分组 分支 非捕获组 反向引用 回文

步骤 · 13

  1. 01用括号打包讲解
  2. 02分组是一个单元狩猎
  3. 03作用于分组的量词狩猎
  4. 04用竖线写分支狩猎
  5. 05高亮各个分支狩猎
  6. 06给分支加分组狩猎
  7. 07不捕获的分组狩猎
  8. 08反向引用狩猎
  9. 09五字母回文狩猎
  10. 10重复的单词狩猎
  11. 11可选的分组狩猎
  12. 12高尔夫:重复音节狩猎
  13. 13捕获与调用已掌握讲解

正则分组、分支与反向引用

正则表达式中的圆括号构成一个分组:把几个字符当作一个整体。在分组后面加量词,重复的是整个分组,而不只是最后一个字符。在里面放一个竖线 |,就得到分支:一组选项,匹配其中任意一个都行。

普通的分组 ( ) 还会捕获。它记住自己匹配到的确切文本,而像 \1 这样的反向引用会要求同样的文本在正则后面再出现一次。正则就是靠它找出重复的字母、配对的引号或连打了两遍的单词。分组按左括号从左往右编号。

只需要分组、不需要记住内容时,就写非捕获组 (?:...)。它的分组和分支效果完全一样,还能让其他分组的编号保持整齐。在狩猎中,一个放对位置的分组,往往就是“只抓住目标”和“连无辜者也一起抓”的区别。

示例

  1. /^(?:un|re)do$/

    抓住

    • undo
    • redo

    放过

    • do
    • outdo
    • undone

    分组把 un 和 re 之间的选择与其余部分隔开,锚点则挡住更长的单词。

  2. /^(\d{3}-)?\d{4}$/

    抓住

    • 555-0199
    • 0199

    放过

    • 55-0199
    • 555-019
    • 5550-199

    分组后面的 ? 让整个区号连同连字符一起变成可选的,绝不会只出现一半。

  3. /^(ha)+!$/

    抓住

    • ha!
    • haha!
    • hahaha!

    放过

    • hah!
    • ha
    • aha!

    分组后面的 + 重复的是整个 ha,而不只是 a,所以 ! 前面多出一个 h 就会被放过。

  4. /(["']).*\1/

    抓住

    • "hi"
    • 'ok'
    • say 'yo'

    放过

    • "hi'
    • 'ok"
    • no quotes

    反向引用让结尾的引号与开头的引号一致,开头用哪种,结尾就得是哪种。

常见错误

  • 分支没有用括号包起来。 竖线的优先级最低,所以 ^red|blue$ 的意思是 ^red 或 blue$;如果两边都要受锚点约束,请写成 ^(red|blue)$。
  • 用方括号表示单词。 [red|blue] 是一个字符类,匹配该集合中的一个字母(或竖线本身),而不是单词 red 或 blue。
  • 反向引用错位。 在前面新增一个捕获组,后面所有分组都会重新编号,\1 就突然指向别处了;不需要被反向引用的分组请用 (?:...)。

阅读规则:指南中的“分组:捕获与命名” →反复操练:刁钻正则 →

延伸阅读:正则表达式反向引用:让正则记住自己匹配过的内容 →

延伸阅读:正则表达式中的命名组与非捕获组 →