A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lwy0319 高级黑马   /  2014-3-15 16:29  /  1374 人查看  /  3 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 lwy0319 于 2014-3-22 00:16 编辑

大家好,求助一个正则表达式问题
前几天做了道题,从字符串中提取数字
本来可以通过拆分成字符数组再通过循环判断看看是否小于等于9大于等于0,来将数字提取出来
后来好奇之下查了下网上的答案
  1. import java.util.regex.Matcher;
  2. import java.util.regex.Pattern;
  3. public class Test{
  4.         public static void main(String[] args) {
  5.                 String a="I31love23next2343423java12";//输入原字符串
  6.                 String regEx="[^0-9]";//输入规则为:表示取非0-9之间的数字  的字符串 依然String类型
  7.                 Pattern p = Pattern.compile(regEx);//实例化Pattern类型,将之真正转换成代表着正则表达式规则的类
  8.                 Matcher m = p.matcher(a);//用实例化的P规则去验证a字符串
  9.                 System.out.println( m.replaceAll("").trim());//m.replaseAll("")将不满足规则的字符更换成""(空),并返回String类型的字符串
复制代码
因为之前没接触过正则表达式,然后API查到了关于Pattern类的构造方法中非数字的表达如下
字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
  
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
然后试着把String regEx="[^0-9]";这句改成了String regEx="\D";发现不允许,而且根据后来找到说明说"\"本身也是需要转义的,所以改成String regEx="\\D";就对了,但是还是不明白为什么需要转义,而且看原例子String regEx="[^0-9]";中的[^0-9]只是出现在说明文字中不知道是用在API中的哪种规则来定义的?PS:原代码没注释,我补充了下自己的理解关于trim()我不太理解它在这里的必要性,因为之前操作所替换的内容是“”而非"  "(空格),我试着去掉它,发现输出结果没区别,但是不知道这是否是有潜在的区别?或者说是一种良好的习惯?

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

3 个回复

倒序浏览
1、String regEx="[^0-9]"和String regEx="\\D";只是写的方式不同,String regEx="\\D";是一种更简便的写法。因为在用定义的字符的时候,“\D”是一个整体,代表=[^0-9],可是想让编译器编译的最终结果为“\D”,必须要写成为“\\D”的形式,将“\”进行转义。
2、如果后面不加trim(),并把replaceAll(" ")中要替换的字符串换为空格的话,最终结果为:
31    23    2343423    12。当去空格后,才变成为一个字符串,实现将字母都去掉的结果:3123234342312
只写为System.out.println( m.replaceAll(""))替换内容中不加空格,最后的结果也是:3123234342312
trim()主要是去除字符串中单词前后的空格。

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
"\\D"这里之所以需要转义,是因为\是正则表达式中的特殊字符(转义符),也就是说它有特殊含义就像*号、点(.)等,但是有些时候需要匹配这些符号的时候就需要用\进行转义,\D整体表示非数字,所以\要用转义符进行转义写成"\\D",否则写成"\D"的话,就会把第一个\当成转义符进行处理,但是转义没特殊含义的D就会报错。
trim()方式只是用于去掉该字符串首尾处的空白,在这里其实是可以不写的,因为匹配到的非数字字符已经包含了所有的空白字符,这或许只是编写者的一种习惯吧,习惯的好坏不做评论,只要该用到的时候记得写就好

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 lwy0319 于 2014-3-16 00:44 编辑

谢谢回答,关于转义字符大概明白了一些:不过我目前只看到以字符串形式作为输入或者输出的时候那些需要转义的字符就成为了转义字符需要更特别的方式去输入,不知道是否有其它的应用,呃。。还有就是原帖中提到的我查API时候没找到非数字可以用[^0-9]表示的依据,要是之前没看这段代码我可能只会用\D了。。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马