正则基础之--/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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值