快速开始
教程
工具和语言
示例
参考
书籍评论
正则表达式教程
简介
目录
特殊字符
不可打印字符
正则表达式引擎内部
字符类别
字符类别减法
字符类别交集
简写字符类别
单词边界
交替
可选项
重复
分组和捕获
反向引用
反向引用,第 2 部分
命名组
相对反向引用
分支重置组
自由间距和注释
Unicode
模式修饰符
原子分组
占有量词
前瞻和后顾
环顾,第 2 部分
将文本保留在匹配之外
条件
平衡组
递归
子例程
无限递归
递归和量词
递归和捕获
递归和反向引用
递归和回溯
POSIX 方括号表达式
零长度匹配
继续匹配
本网站上的更多内容
简介
正则表达式快速开始
正则表达式教程
替换字符串教程
应用程序和语言
正则表达式示例
正则表达式参考
替换字符串参考
书籍评论
可打印 PDF
关于本网站
RSS 源和博客
RegexBuddy—Better than a regular expression tutorial!

继续上一个匹配的末尾

\G 匹配上一个匹配结束的位置。在第一次匹配尝试期间,\G 匹配 字符串的开头,就像 \A 所做的那样。

对字符串 test string 应用 \G\w 匹配 t。再次应用它匹配 e。第三次尝试产生 s,第四次尝试匹配字符串中的第二个 t。第五次尝试失败。在第五次尝试期间,字符串中唯一匹配 \G 的位置在第二个 t 之后。但该位置后面没有单词字符,因此匹配失败。

上一个匹配的末尾与匹配尝试的开头

对于某些正则表达式风格或工具,\G 在匹配尝试开始时匹配,而不是在上一个匹配的末尾匹配。在 RubyJust Great Software 应用程序 中就是这种情况。在 EditPad Pro 中,\G 在文本光标的位置匹配。找到匹配项后,EditPad Pro 将选择匹配项,并将文本光标移动到匹配项的末尾。结果是,只有在两次搜索之间不移动文本光标时,\G 才在上次匹配结果的末尾匹配。总而言之,这在文本编辑器的上下文中非常有意义。

如果正则表达式可以找到 零长度匹配项,则上一个匹配项的末尾和匹配尝试的开始之间的区别也很重要。大多数正则表达式引擎在零长度匹配项后 在字符串中前进。在这种情况下,匹配尝试的开始比上一个匹配尝试的末尾在字符串中多一个字符。.NETJavaBoost 以这种方式前进,并且还在上一个匹配尝试的末尾匹配 \G。因此,当 .NET、Java 和 Boost 在零长度匹配项后前进时,\G 无法匹配。

Perl 中的 \G 魔术

Perl 中,上次匹配结束的位置是一个“神奇”值,它会针对每个字符串变量单独记住。该位置与任何正则表达式无关。这意味着你可以使用 \G 使正则表达式在另一个正则表达式停止的位置继续在主题字符串中进行匹配。

如果匹配尝试失败,\G 的存储位置将重置为字符串的开头。为避免这种情况,请指定延续修饰符 /c

所有这些对于使多个正则表达式协同工作非常有用。例如,你可以按照以下方式解析 HTML 文件

while ($string =~ m/</g) {
  if ($string =~ m/\GB>/c) {
    # Bold
  } elsif ($string =~ m/\GI>/c) {
    # Italics
  } else {
    # ...etc...
  }
}

while 循环中的正则表达式搜索标签的左括号,而循环内的正则表达式检查我们找到哪个标签。通过这种方式,你可以按文件中的出现顺序解析文件中的标签,而无需编写一个匹配所有你感兴趣的标签的单个大正则表达式。

其他编程语言中的 \G

大多数其他编程语言不具备这种灵活性。例如,在 Java 中,\G 的位置由 Matcher 对象记住。Matcher 严格与单个正则表达式和单个主题字符串关联。不过,你可以添加一行代码,让第二个 Matcher 的匹配尝试从第一个 Matcher 的匹配结束位置开始。然后,\G 将在此位置匹配。

匹配尝试的开始

通常,\A字符串开始锚。但在 Tcl 中,锚 \A 在匹配尝试的开始处匹配,而不是在字符串的开始处匹配。使用 GNU 风格 时,\<(反斜杠反引号)的作用相同。如果你只在 Tcl 中调用一次 regexp 或在 GNU 库中调用一次 regexec(),这没有区别。如果你在第一次匹配之后在字符串的剩余部分查找另一个匹配,则可能会产生区别。\A\< 随后在第一次匹配的末尾匹配,而不是像字符串开始锚通常那样匹配失败。奇怪的是,在 Tcl 或 GNU 库中,插入符号都没有这个问题。