黑马程序员技术交流社区

标题: 关于正则表达式边界适配器“\B”的问题! [打印本页]

作者: 王晓明    时间: 2013-1-13 21:31
标题: 关于正则表达式边界适配器“\B”的问题!
本帖最后由 王晓明 于 2013-1-13 21:34 编辑

今天发现一问题,就是在正则表达式中,我们知道边界匹配器中\w的意思是非字母边界!
但是在我进行了验证之后,发现,这一边界适配器的定义有问题:源代码如下:
/**
* <pre>
* \w 单词字符:[a-zA-Z_0-9]
*
*  边界匹配器
                 ^ 行的开头
                 $ 行的结尾
                 \b 单词边界
                 \B 非单词边界
                 \A 输入的开头
                 \G 上一个匹配的结尾
                 \Z 输入的结尾,仅用于最后的结束符(如果有的话)
                 \z 输入的结尾

* </pre>
* */
public class Demo1 {
        public static void main(String[] args) {
                String str = "aaddccd";
                System.out.println(str.matches("\\b\\w+\\b"));//true
                String str2 = "aaddccd.";
                System.out.println(str2.matches("\\b\\w+\\B"));//flase
                String str3 = "aaddccd!";//按照\w的定义,!应该是非单词字符
                System.out.println(str3.matches("\\b\\w+\\B"));//flase
                String str4 = "~";//同理:按照\w的定义,~应该是非单词字符
                System.out.println(str4.matches("\\B"));//flase
                String str5 = "|";
                System.out.println(str5.matches("\\B"));//flase
        }
}


其中我进行了多方测试,均不能返回true!

根据API文档的翻译,我们知道\w表示的意思:
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]

也就是说像“~、!、#”等符号都是非单词符号的,应该能够使用\B进行验证的。
如上面的代码,我专门测试了\B(如第4、5个例子),发现还是返回的false。

不知道这是怎么回事,是JDK的定义问题?还是我未发现的小细节出了问题?
求达人解惑,以上代码大家可以拷贝试一下!

作者: 铿锵科技    时间: 2013-1-13 23:15
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]

也就是说像“~、!、#”等符号都是非单词符号的,应该能够使用\B进行验证的。
如上面的代码,我专门测试了\B(如第4、5个例子),发现还是返回的false。
答:
非单词有很多,即非单词的对象有很多,而\B只代表一个对象,所以比较为false
作者: 王晓明    时间: 2013-1-15 12:58
铿锵科技 发表于 2013-1-13 23:15
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]

你的解释很。。。
我知道非单词有很多,但是\B只是判断是否是以非单词为边界的,与非单词的数量无关!安装它的定义,只要是非单词边界,就应该返回true,但是测试相反!所以疑惑的是关于\B的定义!
作者: 肖亚光    时间: 2013-1-15 13:21
我感觉你可能理解错误\b 和\B的意义了
你可以试着用\B来获取符合正则的字符串 就容易理解\B的意义了。
按我的理解\B最多是用来获取
比如aaabsgcgs!jsfshb 如果用\B来获取的话 就很容获取到了!前面的字符串了  
所以你想 怎么能用\B 来matches()呢?我感觉它永远不会获取到整个字符串,因为它到不了单词的边界。所以也就不能用matches()方法来匹配整个字符串
作者: 王晓明    时间: 2013-1-15 13:37
可乐咖啡厅 发表于 2013-1-15 13:21
我感觉你可能理解错误\b 和\B的意义了
你可以试着用\B来获取符合正则的字符串 就容易理解\B的意义了。
按我 ...

呃,你的答案我看着比较费解!
按你的理解\B是用来获取?!
\B是边界适配器,属于判断的正则表达式,它返回的是boolean类型的啊!它也只是判断是否是以非单词为边界的!\b就没有问题(如我的第一个代码例子),难得说\B是另外的意思?
你怎么会说是用于获取的呢?如果是你这么理解的话,那\B的定义岂不是有些矛盾?或者说你直接给我一段代码,看看一下你的理解吧!
作者: 肖亚光    时间: 2013-1-15 13:42
\B是非单词边界 和你说的是以非单词为边界  完全是两个意思....
"abcd"  到c的时候是不是到单词边界了呢?答案是没有到单词边界。那么\B就是这个意思 而不是你说的单单以非单词为边界
当然"abcd!aaa" 到d的时候是不是非单词的边界呢。当然也是了。
  1. import java.util.regex.*;
  2. public class Demo1 {
  3.         public static void main(String[] args) {
  4.                 String str = "aaddccd";
  5.                 System.out.println(str.matches("\\b\\w+\\b"));//true
  6.                 String str2 = "aaddccd.";
  7.                 System.out.println(str2.matches("\\b\\w+\\B"));//flase
  8.                 String str3 = "aaddcca!";//按照\w的定义,!应该是非单词字符
  9.                                 String regex = "\\b\\w+\\B";
  10.                                 Pattern pattern = Pattern.compile(regex);
  11.                                 Matcher matcher = pattern.matcher(str3);
  12.                                 if(matcher.find())
  13.                                         System.out.println(matcher.group());
  14.                 System.out.println(str3.matches("\\b\\w+\\B\\a"));//flase
  15.                 String str4 = "~";//同理:按照\w的定义,~应该是非单词字符
  16.                 System.out.println(str4.matches("\\B"));//flase
  17.                 String str5 = "|";
  18.                 System.out.println(str5.matches("\\B"));//flase
  19.         }
  20. }
复制代码
这里你打印一下试试各个不同的字符串就知道了
作者: 肖亚光    时间: 2013-1-15 13:50
\B是非单词边界  如果让他去匹配整个字符串。我们知道只要是字符串就得有结束的时候,哪怕其中都是单词字符,那到了最后一个字符同样是到了单词的结尾。所以肯定不符合规则,也就是false
例如"abcdefg" 匹配的时候到f还是符合规则的,到g的时候发现是单词的边界,这时候就不符合规则了,当然会打印false;
例如"abc!def"到c的时候符合规则,到!的时候就不符合规则了。所以结果还是false
作者: Rancho_Gump    时间: 2013-1-15 14:16
String str5 = "!";
                System.out.println(str5.matches("\\B"));//flase
\B匹配的是非单词边界 没问题
为flase的原因是:"\\B" 规则下第一字符为空字符""   "!"为一个字符  所以想要匹配"!"  得用"\\B[!]" 此时为true
符合"\\B"规则的字符串为是""     不知道明白没
作者: 王晓明    时间: 2013-1-16 21:10
很感谢各位,鄙人在线时间短,问了问题也没什么时间来看答案,前天中午在线了一小时,多谢肖亚光 同学的在线答复!事后结合同学的解惑,我基本懂了!很感谢你的答复!同时也感谢张向辉同学的答复,你的虽然简单,但是简单易懂,相信和我一样疑惑的人一眼就能看明白!十分感谢!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2