正则基础之 \b 单词边界

1概述
“\b”匹配单词边界,不匹配任何字符。
“\b”匹配的只是一个位置,这个位置的一侧是构成单词的字符,另一侧为非单词字符、字符串的开始或结束位置。“\b”是零宽度的。
基本上所有的资料里都会说“\b”是单词边界,但是关于“单词”的范围却是少有提及。通常情况下,正则表达式中所谓的“单词”,就是由“\w”所定义的字符所组成的子串。
“\b”表示所在位置的一侧为单词字符,另一侧为非单词字符、字符串的开始或结束位置,也就相当于
(?<!\w)(?=\w)|(?<=\w)(?!\w)
思考:以下写法为什么不等价于“\b”
(?<=\W)(?=\w)|(?<=\w)(?=\W)
2\w的范围
即然涉及到“\w”,那就要先考察一下它的范围。
在支持ASCII码的语言中,如JavaScript,“\w”等价于[a-zA-Z0-9_] ;
在支持Unicode的语言中,如.NET,默认情况下,“\w”除可以匹配[a-zA-Z0-9_]外,还可以匹配一些Unicode字符集,如汉字,全角数字等等。
几乎所有常见的语言都遵循这样一个规律,只有Java是个例外。在Java中,“\w”的表现是比较奇怪的,Java是支持Unicode的,但Java的正则中的“\w”却是等价于[a-zA-Z0-9_]的。
先来看一下“\w”在几种语言中匹配的例子
JavaScript


代码如下:

<script language="javascript">
var str = "abc_123中文_d3=efg汉字%";
var reg = /\w+/g;
var arr = str.match(reg);
if(arr != null)
{
for(var i=0;i<arr.length;i++)
{
document.write(arr[i] + "<br />");
}
}
</script>
//JavaScript中输出
abc_123
_d3
efg

C#


代码如下:

string test = "abc_123中文_d3=efg汉字%";
MatchCollection mc = Regex.Matches(test, @"\w+");
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}
//C#中输出
abc_123中文_d3
efg汉字

Java


代码如下:

String test = "abc_123中文_d3=efg汉字%";
String reg = "\\w+";
Matcher m = Pattern.compile(reg).matcher(test);
while(m.find())
{
System.out.println(m.group());
}
//Java中输出
abc_123
_d3
efg

可以看到,“\w”在Java中的输出和JavaScript中是一样的,都是只支持ASCII字符。
3 \b的范围
常见语言中“\w”的范围确定了,那么是不是可以认为“\b”的匹配范围与“\w”也是一致的呢?
再看下下面的例子:
源字符串:abc_123中文_d3=汉字efg
正则表达式:.\b.
JavaScript


代码如下:

<script language="javascript">
var str = "abc_123中文_d3=efg汉字%";
var reg = /.\b./g;
var arr = str.match(reg);
if(arr != null)
{
for(var i=0;i<arr.length;i++)
{
document.write(arr[i] + "<br />");
}
}
</script>
//JavaScript中输出
3中
文_
3=
g汉

C#


代码如下:

string test = "abc_123中文_d3=efg汉字%";
MatchCollection mc = Regex.Matches(test, @".\b.");
foreach (Match m in mc)
{
richTextBox2.Text += m.Value + "\n";
}
//C#中输出
3=
字%

Java


代码如下:

String test = "abc_123中文_d3=efg汉字%";
String reg = ".\\b.";
Matcher m = Pattern.compile(reg).matcher(test);
while(m.find())
{
System.out.println(m.group());
}
//Java中输出
3=
字%

可以看到,Java的输出和.NET是一致的,“\b”在Java中是支持Unicode的。
所以总的来说,Java中的“\w”是很奇怪的,而“\b”是与其它语言表现一致的,在使用时需要注意。
4 \b应用场景
4.1 基础应用
“\b”一般应用在需要匹配某一单词字符组成的子串,但这一字符不能包含在同样由单词字符组成的更长的子串中。
比如要替换掉一段英文中的单词“to”,而“today”显然不在替换的范围内,所以正则可以用“\bto\b”来限定。
用得比较多的场景是在HTML标签的匹配中,用以区分相互包含的标签,比如要过滤掉<b>、</b>、<p…>、<img…>等标签,但要保留<br />标签,正则可以写成“<(/?b|p|img)\b[^>]*>”。
举例:统计以“,”分割的元素中“3”的个数
string test = "137,1,33,4,3,6,21,3,35,93,2,98";
int count = Regex.Matches(test, @"\b3\b").Count; //结果:2
4.2 进阶应用
稍复杂一些的应用通常都是与其它一些正则语法规则一起使用的,参考一个帖子
求一正则表达式
4.3 特殊情况
“\b”用在正则中,通常情况下都是表示单词边界的,只有在字符组中,它表示的是退格键,即
[a-z\b]
此处的“\b”表示的是退格键,而不是单词边界。

(0)

相关推荐

  • 正则基础之 \b 单词边界

    1概述 "\b"匹配单词边界,不匹配任何字符. "\b"匹配的只是一个位置,这个位置的一侧是构成单词的字符,另一侧为非单词字符.字符串的开始或结束位置."\b"是零宽度的. 基本上所有的资料里都会说"\b"是单词边界,但是关于"单词"的范围却是少有提及.通常情况下,正则表达式中所谓的"单词",就是由"\w"所定义的字符所组成的子串. "\b"表示所

  • 正则基础之 神奇的转义

    1 概述这或许会是一个让人迷惑,甚至感到混乱的话题,但也正因为如此,才有了讨论的必要.在正则中,一些具有特殊意义的字符,或是字符序列,被称作元字符,如"?"表示被修饰的子表达式匹配0次或1次,"(?i)"表示忽略大小写的匹配模式等等.而当这些元字符被要求匹配其本身时,就要进行转义处理了.不同的语言或应用场景下,正则定义方式.元字符出现的位置不同,转义的方式也是林林总总,不一而同.2 .NET正则中的字符转义2.1     .NET正则中的转义符绝大多数语言中,&qu

  • 正则基础之 环视 Lookaround

    1       环视基础 环视只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果,是零宽度的.环视匹配的最终结果就是一个位置. 环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功. 环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视.顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件. 表达式 说明 (?<=Expression) 逆序肯定环视,表示所在位置左侧能够匹配Exp

  • 正则基础之 NFA引擎匹配原理

    1       为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或许不知道该如何去改变音符的组合,使得乐曲更动听. 作为正则的使用者也一样,不懂正则引擎原理的情况下,同样可以写出满足需求的正则,但是不知道原理,却很难写出高效且没有隐患的正则.所以对于经常使用正则,或是有兴趣深入学习正则的人,还是有必要了解一下正则引擎的匹配原理的. 2       正则表达式引擎

  • 正则基础之 小数点

    一些细节 对于使用传统NFA引擎的大多数语言和工具,如Java..NET来说,"."的匹配范围是匹配除了换行符"\n"以外的任意一个字符. 但是对于javascript来说有些特殊,由于各浏览器的解析引擎不同,"."的匹配范围也有所不同,对于Trident内核的浏览器,如IE来说,"."同样是匹配除了换行符"\n"以外的任意一个字符,但是对于其它内核的浏览器,如Firefox.Opera.Chrome来说,

  • jQuery中的正则表达式分析 正则基础

    quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/ (?:-)表示是一个非捕获型 [^<]表示是以"<"起始,包含0个或多个'<'括号 (<[\w\W]+>)表示是一个捕获型,以'<>'起始,中间包含一个或多个字符 $表示字符的结尾 (#([\w\-]+))表示是一个捕获型,以'#'号和字符串.数字._以及-组成 rnotwhite = /\S/ \S表示是空白字符

  • JS:正则将首字单词转成大写

    [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]

  • .net indexOf(String.indexOf 方法)

    返回 String 对象内第一次出现子字符串的字符位置. public indexOf(value:String, [startIndex:Number]) : Number 搜索字符串,并返回在调用字符串内 startIndex 位置上或之后找到的 value 的第一个匹配项的位置.此索引从零开始,这意味着字符串中的第一个字符被视为位于索引 0 而不是索引 1 处.如果未找到 value,该方法会返回 -1. 参数 value:String - 一个字符串:要搜索的子字符串. startInd

  • String.indexOf 方法介绍

    字符串的IndexOf()方法搜索在该字符串上是否出现了作为参数传递的字符串,如果找到字符串,则返回字符的起始位置 (0表示第一个字符,1表示第二个字符依此类推)如果说没有找到则返回 -1 返回 String 对象内第一次出现子字符串的字符位置. 复制代码 代码如下: public indexOf(value:String, [startIndex:Number]) : Number 搜索字符串,并返回在调用字符串内 startIndex 位置上或之后找到的 value 的第一个匹配项的位置.此

  • PHP正则表达式完全教程之基础篇

    目前,正则表达式已经在很多软件中得到广泛的应用,包括*nix(Linux, Unix等),HP等操作系统,PHP,C#,Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子. 正则表达式的使用,可以通过简单的办法来实现强大的功能. 为了简单有效而又不失强大,造成了正则表达式代码的难度较大,学习起来也不是很容易. 例子: ^.+@.+..+$ 这样的代码曾经多次把我自己给吓退过.可能很多人也是被这样的代码给吓跑的吧. 学习完本教程将让你也可以自由应用这样的代码. 正则表达式的历史

随机推荐