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

词边界

元字符 \b 是一个 ,类似于脱字符和美元符号。它在称为“词边界”的位置匹配。此匹配为零长度。

有三个不同的位置符合词边界

简单来说:\b 允许你使用 \bword\b 形式的正则表达式执行“仅限整个单词”搜索。一个“单词字符”是一个可用于形成单词的字符。所有不是“单词字符”的字符都是“非单词字符”。

具体哪些字符是单词字符取决于你使用的正则表达式类型。在大多数类型中,与简写字符类 \w匹配的字符是单词边界视为单词字符的字符。Java是个例外。Java 支持 \b 的 Unicode,但不支持 \w 的 Unicode。

除了下面讨论的类型之外,大多数类型只有一个元字符既匹配单词前又匹配单词后。这是因为字符之间的任何位置都不可能既在单词的开头又在单词的结尾。只使用一个运算符可以让你更轻松。

由于数字被视为单词字符,因此 \b4\b 可用于匹配不属于较大数字的 4。此正则表达式不匹配 44 sheets of a4。因此,说“\b 匹配字母数字序列前后的内容”比说“单词前后的内容”更准确。

\B\b 的否定版本。\B 匹配 \b 不匹配的每个位置。实际上,\B 匹配两个单词字符之间的任何位置以及两个非单词字符之间的任何位置。

查看正则表达式引擎内部

让我们看看当我们将正则表达式 \bis\b 应用于字符串 This island is beautiful 时会发生什么。引擎从第一个字符 T 处的第一个标记 \b 开始。由于此标记的长度为零,因此会检查字符前的位置。\b 在此处匹配,因为 T 是一个单词字符,而它前面的字符是字符串开头前的空字符。引擎继续使用下一个标记:文字 i。引擎不会前进到字符串中的下一个字符,因为上一个正则表达式标记的长度为零。i 不匹配 T,因此引擎在下一个字符位置重试第一个标记。

\b 无法匹配 Th 之间的位置。它也不能匹配 hi 之间的位置,也不能匹配 is 之间的位置。

字符串中的下一个字符是空格。 \b 在此处匹配,因为空格不是单词字符,而前一个字符是。同样,引擎继续使用 i,它与空格不匹配。

前进一个字符并从第一个正则表达式标记重新开始,\b 在空格和字符串中的第二个 i 之间匹配。继续,正则表达式引擎发现 i 匹配 is 匹配 s。现在,引擎尝试在 l 之前的那个位置匹配第二个 \b。这将失败,因为这个位置介于两个单词字符之间。引擎恢复到正则表达式的开头,并前进一个字符到 island 中的 s。同样,\b 无法匹配,并一直继续,直到到达第二个空格。它在那里匹配,但匹配 i 失败。

但是 \b 在字符串中第三个 i 之前的那个位置匹配。引擎继续,并发现 i 匹配 is 匹配 s。正则表达式中的最后一个标记 \b 也在字符串中第三个空格之前的那个位置匹配,因为空格不是单词字符,而它之前的字符是。

引擎已成功匹配我们字符串中的单词 is,跳过了 i 和 s 字符的前面两个出现。如果我们使用正则表达式 is,它将匹配 This 中的 is

Tcl 词边界

如上所述,大多数正则表达式风格都支持词边界。值得注意的例外是 POSIXXML Schema 风格,它们根本不支持词边界。 Tcl 使用不同的语法。

在 Tcl 中,\b 匹配退格字符,就像大多数正则表达式风格(包括 Tcl)中的 \x08 一样。 \B 在 Tcl 中匹配单个反斜杠字符,就像所有其他正则表达式风格(以及 Tcl)中的 \\ 一样。

Tcl 使用字母“y”代替字母“b”来匹配单词边界。\y 匹配任何单词边界位置,而 \Y 匹配任何不是单词边界的位置。这些 Tcl 正则表达式标记与 Perl 风格正则表达式中的 \b\B 完全匹配。它们不区分单词的开头和结尾。

Tcl 还有两个单词边界标记,它们区分单词的开头和结尾。\m 仅匹配单词的开头。也就是说,它匹配其左侧为非单词字符且右侧为单词字符的任何位置。如果字符串中的第一个字符是单词字符,它还匹配字符串的开头。\M 仅匹配单词的结尾。它匹配其左侧为单词字符且右侧为非单词字符的任何位置。如果字符串中的最后一个字符是单词字符,它还匹配字符串的结尾。

除了 Tcl 本身之外,唯一支持 Tcl 风格单词边界的正则表达式引擎是 JGsoft 引擎。在 PowerGREPEditPad Pro 中,\b\B 是 Perl 风格的单词边界,而 \y\Y\m\M 是 Tcl 风格的单词边界。

在大多数情况下,缺少 \m\M 令牌并非问题。 \yword\y 仅查找“whole words only”出现的“word”,就像 \mword\M 所做的那样。 \Mword\m 永远无法匹配任何位置,因为 \M 永远不会匹配在单词字符后面紧跟的位置,而 \m 永远不会匹配在单词字符前面紧跟的位置。如果你的正则表达式需要匹配 \y 之前或之后的字符,你可以在正则表达式中轻松指定这些字符应该是单词字符还是非单词字符。如果你想匹配任何单词,\y\w+\y 给出的结果与 \m.+\M 相同。使用 \w 代替点自动将第一个 \y 限制为单词的开头,并将第二个 \y 限制为单词的结尾。请注意,\y.+\y 不会起作用。此正则表达式匹配每个单词,还匹配主题字符串中单词之间的每个非单词字符序列。也就是说,如果你的风格支持 \m\M,正则表达式引擎可以应用 \m\w+\M,其速度比 \y\w+\y 略快,具体取决于其内部优化。

如果你的正则表达式风格支持 前瞻和后顾,你可以使用 (?<!\w)(?=\w) 来模拟 Tcl 的 \m,并使用 (?<=\w)(?!\w) 来模拟 \M。尽管冗长得多,但这些前瞻结构与 Tcl 的单词边界完全匹配。

如果您的风格具有前瞻但没有后顾,并且还具有 Perl 风格的单词边界,您可以使用 \b(?=\w) 来模拟 Tcl 的 \m\b(?!\w) 来模拟 \M\b 匹配单词的开头或结尾,前瞻检查下一个字符是否属于单词的一部分。如果是,我们处于单词的开头。否则,我们处于单词的结尾。

GNU 单词边界

对 POSIX 正则表达式的 GNU 扩展 添加了对 \b\B 单词边界的支持,如上所述。GNU 还使用自己的语法来表示单词开头的边界和单词结尾的边界。 \< 匹配单词的开头,就像 Tcl 的 \m\> 匹配单词的结尾,就像 Tcl 的 \M

Boost 在使用 ECMAScript、扩展、egrep 或 awk 语法时,也将 \<\> 视为单词边界。

POSIX 单词边界

POSIX 标准将 [[:<:]] 定义为单词开头的边界,将 [[:>:]] 定义为单词结尾的边界。虽然语法借鉴自 POSIX 方括号表达式,但这些标记是单词边界,与字符类无关,不能在字符类内部使用。Tcl 和 GNU 也支持 POSIX 单词边界。 PCRE 从 8.34 版开始支持 POSIX 单词边界。Boost 在其所有语法中都支持它们。