读书人

正则表达式quot;\wquot;跟quot;\bquot;在不同语言中的用

发布时间: 2013-01-27 13:56:15 作者: rapoo

正则表达式"\w"和"\b"在不同语言中的用法注意

?

\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

?

<scriptlanguage="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

?

<scriptlanguage="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应用场景

?

\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

?

稍复杂一些的应用通常都是与其它一些正则语法规则一起使用的,参考一个帖子 求一正则表达式

?

\b”用在正则中,通常情况下都是表示单词边界的,只有在字符组中,它表示的是退格键,即

?

[a-z\b]

?

此处的“\b”表示的是退格键,而不是单词边界。

?

读书人网 >编程

热点推荐