正则基础之——/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 ”表示的是退格键,而不是单词边界。

你可能感兴趣的:(JavaScript,java,.net,String,正则表达式,语言)