《正则表达式经典实例(第2版)》——2.6 匹配完整单词

2.6 匹配完整单词

问题描述
创建一个正则表达式来匹配My cat is brown中的cat,同时不能匹配category或是bobcat。再创建一个正则表达式来匹配staccato中的cat,同时不能匹配到上面的3个目标字串。

解决方案
单词边界

\bcat\b
正则选项:无
正则流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby

非单词边界

\Bcat\B
正则选项:无
正则流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby

讨论
单词边界
正则表达式记号‹b›被称作是单词边界(word boundary)。它会匹配一个单词的开始或结束。就它自身而言,所产生的是一个长度为0的匹配。‹b›也是一个定位符,这与在前一个小节中介绍过的记号是一样的。

严格来讲,‹b›会匹配如下3种位置:

在目标文本的第一个字符之前,如果第一个字符是单词字符;
在目标文本的最后一个字符之后,如果最后一个字符是单词字符;
在目标文本的两个字符之间,其中一个是单词字符,而另外一个不是单词字符。
如果要使用正则表达式来进行“只匹配完整单词”的查找,那么只需要把该单词放在两个单词边界之间,就像我们前面给出的‹bcatb›。第一个‹b›要求‹c›出现在字符串的最开始处,或者是在一个非单词字符后面。第二个‹b›要求‹t›出现在字符串的最末尾处,或者是在一个非单词字符前面。换行符被认为是非单词字符。如果换行符紧跟在一个单词字符后面,那么‹b›会匹配换行符后面的位置。它同样会匹配紧跟着一个单词字符之前的换行符。这样的话,一个占据了一整行的单词也可以通过一个“只匹配完整单词”的查找来发现。‹b›不会受到“多行”模式或是‹(?m)›的影响,这也是本书把“多行”模式称为“^和$匹配换行处”的原因之一。

本书中介绍的所有流派都不提供可以只匹配单词之前或者只匹配单词之后的单独记号。除非想要创建一个正则式只包含单词边界,而不包含任何其他内容,否则这些单独记号是不必要的。在正则表达式中,位于‹b›之前和之后的记号会决定‹b›可以匹配的位置。在‹bx›和‹!b›中的‹b›只会匹配一个单词的开始。而在‹xb›和‹b!›中的‹b›只会匹配一个单词的结束。‹xbx›和‹!b!›则永远不会匹配任何位置。

如果确实只想匹配一个单词之前或之后的位置,可以使用顺序环视(lookahead)和逆序环视(lookbehind)。实例2.16讲解了顺序环视和逆序环视。这种方法无法在JavaScript和Ruby 1.8中使用,因为它们不支持逆序环视。正则式‹(?

非单词边界
‹B›会匹配在目标文本中‹b›不匹配的每一个位置。换句话说,‹B›会匹配不属于单词开始或结束的每一个位置。

严格来讲,‹B›匹配如下5个位置:

在目标文本的第一个字符之前,如果第一个字符不是单词字符;
在目标文本的最后一个字符之后,如果最后一个字符不是单词字符;
在两个单词字符之间;
在两个非单词字符之间;
空串。
‹BcatB›会匹配staccato中的cat。但是不会匹配My cat is brown、category或者bobcat中的cat。

如果想要进行与“只匹配完整单词”相反的查找(也就是说,不包括My cat is brown,但是包括staccato、category和bobcat),就需要采用多选结构来把‹Bcat›和‹catB›组合成为‹Bcat|catB›。其中,‹Bcat›会匹配staccato和bobcat中的cat。‹catB›会匹配category中的cat(如果‹Bcat›没有匹配到,那么它也可以匹配staccato)。实例2.8会详细讲解多选结构。

单词字符
我们前面一直在讲单词边界,但是却没有涉及什么是单词字符(word character)。单词字符就是可以在单词中出现的字符。在实例2.3中的“简写”小节中,我们讨论了哪些字符是包含在‹w›中的,即单个的单词字符。但是,对于‹b›来说情形则有些不同。

虽然本书中的所有流派都支持‹b›和‹B›,但是它们对于到底哪些字符属于单词字符则有所不同。

在.NET、JavaScript、PCRE、Perl、Python和Ruby中,‹b›都会匹配两个字符之间的位置,其中一个字符可以由‹w›匹配,而另外一个字符则可以由‹W›匹配。‹B›则总是匹配同时被‹w›或‹W›匹配的两个字符之间的位置。

JavaScript、PCRE和Ruby只把ASCII字符看做是单词字符。‹w›因此与‹[a-zA-Z0-9_]›是完全等同的。在这些流派中,你可以对像英语这样的,单词完全由不含读音符号的A到Z的字母组成的情况,进行“只匹配完整单词”的查找。但是这些流派对于其他语言,如西班牙语或俄语,就无法进行“只匹配完整单词”的查找。

.NET把所有语言字母表中的字母和数字都当作单词字符。你可以对任意语言中的单词进行“只匹配完整单词”的查找,这其中也包括不使用拉丁字母的语言。

Python则为你提供了一个选项。在Python 2.x中,只有在创建正则式时传递了UNICODE或是U标志,非ASCII的字符才会被包括进来。在Python 3.x中,则默认包含非ASCII字符,不过可以使用ASCII或A标志排除它们。这些标志会对‹b›和‹w›产生相同的影响。

在Perl中,则Perl的版本和/adlu标志决定‹w›是纯ASCII字符还是包括全部Unicode字母、数字和下划线。实例2.3“简写”一节讲解了更多细节。在所有的Perl版本中,‹b›与‹w›保持一致。

Java则表现得不是很一致。在Java 4到Java 6中,‹w›只匹配ASCII字符。在Java 7中,‹w›默认值匹配ASCII字符,如果设置了UNICODE_CHARACTER_CLASS标志则也匹配Unicode字符。但是Java所有版本‹b›都是支持Unicode的,包括任何字母表。在Java 4到Java 6中,‹bwb›会匹配一个单个的英语字母、数字或是在任何语言中都不会作为单词一部分出现的下划线。‹bкошкаb›会正确匹配cat在俄语中对应的单词,因为‹b›是支持Unicode的。但是‹w+›不会匹配任何泰国语单词,因为在Java 4到Java 6中‹w›只会匹配ASCII字符。

时间: 2024-11-01 23:19:50

《正则表达式经典实例(第2版)》——2.6 匹配完整单词的相关文章

《正则表达式经典实例(第2版)》——2.9 分组和捕获匹配中的子串

2.9 分组和捕获匹配中的子串 问题描述 改进匹配Mary.Jane或Sue的正则表达式,使之只能匹配完整单词.使用分组来实现这个功能,整个正则表达式只需要一对单词分界符,而不是给每个选择分支都使用一对分界符. 创建一个正则表达式,使之匹配yyyy-mm-dd格式的任意日期,并且分别捕获年.月和日.目标是在处理匹配的代码中可以更容易处理这些分别捕获的值.你可以假设目标文本中的所有日期都是合法的.正则表达式不必要考虑去掉像9999-99-99这样的非法数据,因为它们根本不可能出现在目标文本中. 解

《正则表达式经典实例(第2版)》——导读

** 前言 **正则表达式在过去十多年间越来越普及.如今,所有常用的编程语言都会包含一个强大的正则表达式函数库,甚至在语言本身就内嵌了对于正则表达式的支持.许多开发人员都会利用这些正则表达式的功能,在应用程序中为用户提供使用正则表达式对其数据进行查找或者过滤的能力.正则表达式已经无处不在.随着正则表达式的广泛采用,出现了许多相关的著作.其中大多数都很好地讲解了正则表达式的语法,并且还会提供一些例子以及参考实现.然而,我们还没有看到有任何一本书能够针对处理计算机和不同因特网应用上的文本所遇到的各种

《正则表达式经典实例(第2版)》——2.3 匹配多个字符之一

2.3 匹配多个字符之一 问题描述 创建一个正则表达式来匹配calendar的所有常见的错误拼写形式,使你能够在一份文档中找到这个单词而无需依赖作者的拼写能力.在每个元音位置都允许使用a或者e.创建另外一个正则表达式来匹配一个单个的十六进制字符.再创建一个正则表达式来匹配不属于十六进制字符的单个字符. 本节中的这个问题用于解释一个重要的.经常使用的正则结构-字符组(character class). 解决方案 错误拼写的calendar c[ae]l[ae]nd[ae]r 正则选项:无 正则流派

半小时精通正则表达式 经典实例介绍_正则表达式

开篇,还是得说说 ^ 和 $ 他们是分别用来匹配字符串的开始和结束,以下分别举例说明 如果您是新手,猜你取消 正则表达式30分钟入门教程"^The": 开头一定要有"The"字符串; "of despair$": 结尾一定要有"of despair" 的字符串; 那么, "^abc$": 就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配 "notice": 匹配包含no

半小时精通正则表达式 经典实例介绍

开篇,还是得说说 ^ 和 $ 他们是分别用来匹配字符串的开始和结束,以下分别举例说明 如果您是新手,猜你取消 正则表达式30分钟入门教程 "^The": 开头一定要有"The"字符串; "of despair$": 结尾一定要有"of despair" 的字符串; 那么, "^abc$": 就是要求以abc开头和以abc结尾的字符串,实际上是只有abc匹配 "notice": 匹配包含n

《正则表达式经典实例(第2版)》——1.3 正则表达式工具

1.3 正则表达式工具 除非已经拥有了相当长的使用正则表达式编程的经验,否则建议你先在一个工具中试验一下正则表达式,而不是直接在源代码中使用它们.本章和第2章中提供的正则表达式示例都是原始正则表达式,其中并不包含编程语言(即使是Unlx shell)所必需的额外的转义符号.因此可以直接把这些正则表达式输入到一个应用程序的查找框中. 第3章讲解如何把正则表达式整合到源代码中.把一个字面的(literal)正则表达式作为一个字符串引用,会让它更加难懂,因为字符串的转义规则会与正则表达式的转义规则混杂

《正则表达式经典实例(第2版)》——2.2 匹配不可打印字符

2.2 匹配不可打印字符 问题描述 匹配一个包含下列ASCII控制字符的字符串:振铃符(bell).转义符(escape).换页符(form feed).换行符(line feed).回车符(carriage return).水平制表符(horizontal tab)和垂直制表符(vertical tab).这些字符的十六进制ASCII编码分别是07.1B.0C.0A.0D.09.0B. 下面演示了转义序列的用法,以及如何以十六进制编码代表字符. 解决方案 \a\e\f\n\r\t\v 正则选项

《正则表达式经典实例(第2版)》——第 1 章 正则表达式简介 1.1正则表达式的定义

第 1 章 正则表达式简介 在你打开这本书的时候,很可能已经热切地期望,要在代码中插入本书中找到的那些包含诸多括号和问号的古怪字符串了.如果你已经准备好要"即查即用",我们非常欢迎,第4-9章中会列出并讲解了各种实用的正则表达式. 但是如果阅读本书的前几章,你将为未来节省大量的时间.例如,本章会向读者介绍许多工具-其中一些工具是本书作者之一的Jan所开发的,这些工具可以帮你事先测试和调试正则表达式,而不用等到把它们塞到代码中之后再处理,那时候查找错误就非常困难了.而且开始这几章还会展示

《正则表达式经典实例(第2版)》——2.14 消除不必要的回溯

2.14 消除不必要的回溯 问题描述上一个实例解释了贪心和懒惰量词之间的区别,以及它们是如何进行回溯的.在有些情形下,这种回溯是不必要的. ‹bd+b›使用了一个贪心量词,而‹bd+?b›使用的是懒惰量词.它们都会匹配相同的内容:一个整数.如果给它们同样的目标文本,它们都会找到完全一样的匹配.在这里所做的任何回溯都是不必要的.试着改写这个正则表达式,明确地消除所有回溯,使正则表达式更加高效. 解决方案 \b\d++\b 正则选项:无 正则流派:Java.PCRE.Perl 5.10.Ruby 1