具有多个匹配的边界

当你的输入具有明确定义的边界并且期望在字符串中有多个匹配时,你有两个选择:

  • 使用惰性量词;
  • 使用否定的字符类。

考虑以下:

你有一个简单的模板引擎,你想要替换像 $[foo] 这样的子字符串,其中 foo 可以是任何字符串。你希望将此子字符串替换为基于 [] 之间的部分。

你可以尝试像\$\[(.*)\] 这样的东西,然后使用第一个捕获组。

这个问题是如果你有一个类似 something $[foo] lalala $[bar] something else 的字符串,你的匹配就是

something $[foo] lalala $[bar] something else
          | \______CG1______/|
          \_______Match______/

捕获组是 foo] lalala $[bar,可能有效也可能无效。

你有两个解决方案

  1. 使用懒惰:在这种情况下,让懒惰成为寻找正确事物的一种方法。所以你把表达改为\$\[(.*?)\]

  2. 使用否定的字符类:ti​​huan9 你将表达式改为\$\[([^\]]*)\]

在两种解决方案中,结果都是相同的:

something $[foo] lalala $[bar] something else
          | \_/|        | \_/|
          \____/        \____/

捕获组分别为 foobar

使用否定字符类可以减少回溯问题,并且可以在大输入时节省 CPU 大量时间。