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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 崔司龙 中级黑马   /  2015-6-27 22:15  /  1661 人查看  /  4 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

  许多语言,包括Perl、PHP、Python、JavaScript和JScript,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高级“搜索-替换”功能。所以JAVA语言也不例外。正则表达式已经超出了某种语言或某个系统的局限,成为被人们广为使用的工具,我们完全可以用它来解决实际开发中碰到的一些实际的问题。

       在JDK1.3及之前的JDK版本中并没有包含正则表达式的类,如果要在Java中使用正则表达式必须使用第三方提供的正则表达式库,最有名的就是Jakarta-ORO,Jakarta-ORO库以前叫做OROMatcher,是Daniel Savarese赠送给Jakarta Project的一个开源包。使用的时候首先要创建一个实现了PatternCompiler接口的实例变量以创建一个“模式编译器”,Jakarta-ORO中实现了这个接口的类就是Perl5Compiler,这个类做到了与Perl5的正则表达式完全兼容。Jakarta-ORO的使用是非常简便的,而且效率非常高,支持的正则表达式语法也是非常全的,唯一的缺点就是它不是JDK中的标准包。从JDK1.4开始提供了支持正则表达式API,它们位于java.util.regex包中,由于已经有了标准API,所以本书将会用java.util.regex进行正则表达式的相关操作。

一、正则表达式基础知识


1.1 句点符号
       假设你在玩英文拼字游戏,想要找出三个字母的单词,而且这些单词必须以“t”字母开头,以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内容。要构造出这个正则表达式,你可以使用一个通配符——句点符号“.”。这样,完整的表达式就是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,还匹配“t#n”、“tpn”甚至“t n”,还有其他许多无意义的组合。这是因为句点符号匹配所有字符,包括空格、Tab字符甚至换行符:


1.2 方括号符号
为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“[]”)里面指定看来有意义的字符。此时,只有方括号里面指定的字符才参与匹配。也就是说,正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单

个字符:

1.3 “或”符号
      如果除了上面匹配的所有单词之外,你还想要匹配“toon”,那么,你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配“toon”,使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号,因为方括号只允许匹配单个字符;这里必须使用圆括号“()”。圆括号还可以用来分组。



1.4 表示匹配次数的符号
下表显示了正则表达式的语法:

表 1.1 正则表达式语法
元字符
说明
.
匹配任何单个字符。例如正则表达式“b.g”能匹配如下字符串:“big”、“bug”、“b g”,但是不匹配“buug”。
$
匹配行结束符。例如正则表达式“EJB$”能够匹配字符串“I like EJB”的末尾,但是不能匹配字符串“J2EE Without EJBs!”。
^
匹配一行的开始。例如正则表达式“^Spring”能够匹配字符串“Spring is a J2EE framework”的开始,但是不能匹配“I use Spring in my project”。
*
匹配0至多个在它之前的字符。例如正则表达式“zo*”能匹配“z”以及“zoo”;正则表达式“.*”意味着能够匹配任意字符串。
/
转义符,用来将元字符当作普通的字符来进行匹配。例如正则表达式/$被用来匹配美元符号,而不是行尾;正则表达式/.用来匹配点字符,而不是任何字符的通配符。
[]
匹配括号中的任何一个字符。例如正则表达式“b[aui]g”匹配bug、big和bug,但是不匹配beg。可以在括号中使用连字符“-”来指定字符的区间来简化表示,例如正则表达式[0-9]可以匹配任何数字字符,这样正则表达式“a[]c”就可以匹配“a0c”、“a1c”、“a2c”等字符串;还可以制定多个区间,例如“[A-Za-z]”可以匹配任何大小写字母。还有一个相配合使用的元字符“^”,用在这里并不像前边的那个“^”一样表示匹配行开始,而是表示“排除”,要想匹配除了指定区间之外的字符,就可以在左边的括号和第一个字符之间使用^字符,例如“[^163A-Z]”将能偶匹配除了1、6、3和所有大写字母之外的任何字符。
( )
将 () 之间括起来的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域,这个元字符在字符串提取的时候非常有用。
|
将两个匹配条件进行逻辑“或”运算。'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。
+
匹配前面的子表达式一次或多次。例如正则表达式9+匹配9、99、999等。
?
匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。此元字符还有另外一个用途,就是表示非贪婪模式匹配,后边将有介绍
{n}
匹配确定的 n 次。例如,“e{2}”不能匹配“bed”中的“d”,但是能匹配“seed”中的两个“e”。
{n,}
至少匹配n次。例如,“e{2,}”不能匹配“bed”中的“e”,但能匹配“seeeeeeeed”中的所有“e”。
{n,m}
最少匹配 n 次且最多匹配 m 次。“e{1,3}”将匹配“seeeeeeeed”中的前三个“e”。
    假设我们要在文本文件中搜索美国的社会安全号码。这个号码的格式是999-99-9999。用来匹配它的正则表达式如图一所示。在正则表达式中,连字符(“-”)有着特殊的意义,它表示一个范围,比如从0到9。因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“/”。

      假设进行搜索的时候,你希望连字符号可以出现,也可以不出现——即,999-99-9999和999999999都属于正确的格式。这时,你可以在连字符号后面加上“?”数量限定符号。

      美国汽车牌照的一种格式是四个数字加上二个字母。它的正则表达式前面是数字部分“[0-9]{4}”,再加上字母部分“[A-Z]{2}”。

1.5 “否”符号
      “^”符号称为“否”符号。如果用在方括号内,“^”表示不想要匹配的字符。例如,图四的正则表达式匹配所有单词,但以“X”字母开头的单词除外。

1.6 圆括号和空白符号

     “/s”符号是空白符号,匹配所有的空白字符,包括Tab字符。如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组,然后用ORO API提取出它的值。

1.7 其它符号

     为简便起见,你可以使用一些为常见正则表达式创建的快捷符号。如以下所示:

   

/t:制表符,等同于/u0009
/n:换行符,等同于/u000A
/d:代表一个数字,等同于[0-9]
/D:代表非数字,等同于[^0-9]
/s:代表换行符、Tab制表符等空白字符
/S:代表非空白字符
/w:字母字符,等同于[a-zA-Z_0-9]
/W:非字母字符,等同于[^/w]
例如,在前面社会安全号码的例子中,所有出现“[0-9]”的地方我们都可以使用“/d”。

4 个回复

倒序浏览
求分享视频
回复 使用道具 举报
【以下为我以前在其他网站写的:】

浅谈正则表达式在文本处理中的应用。

正则表达式是计算机语言里的一个重要组成部分,可以直译为“高级搜索替换功能”,给人比较直观的印象是“匹配”“模糊”“批量”。
因为我们常规的搜索、批量和替换都是准确对应某一个字词句的,而使用正则则可以匹配某一类的符合要求的所有。
大家当然无需掌握所有正则表达式知识,我在这里给大家精简一下好了,掌握我以下所说内容,那么对于文本整理就足够了。

1.逻辑与(字符范围内):[]
就是中括号内任意字符都可查找,比如正则查找[阡陌居],那就是三个字中任意一个字都可以搜索到。

2.逻辑或:|
顾名思义,比如正则查找 阡陌|河洛|文心 ,就是三组字词中任意一组都可以搜索到。会找到阡陌、河洛和文心这三个词。

3.逻辑非(字符范围外):[^]
和第一个正好相反,就是除了中括号内的字符才可查找,比如[^阡陌居],是指这三个字以外的任意字符。

4.回车换行符:\r\n (其中\n是换行符,\r是回车符)
这个在实际应用中通常组合出现,建议大家也一起用,具体原因我也不解释了。
(通常我们用的各种工具的排版功能都是本条正则灵活使用的结果:
比如去除所有空行就是反复正则替换\r\n\r\n为\r\n;行间加一空行则是\r\n替换为\r\n\r\n;行首加两全角空格是\r\n替换为\r\n  等。)

5.任意字符:.
顾名思义,可以匹配任意内容,包括空字符。

6.匹配开始:^
即正则表达式匹配语句的开始。

7.匹配结束:$
即正则表达式匹配语句的结束。

8.重复至少零次:*
显然了,.*连用就是任意字符重复任意次数,即可引申表达任意内容,另注.*不要和\r\n一起使用。

9.重复至少一次:+
.+和.*的意义是一样的,不过.+可以和\r\n一起使用。

10.重复零次或一次:?

11.标记表达式语句:( )
正则表达式中标上括号本身是不会影响语句功能的,加括号为的是替换功能。从左至右,正则搜索语句中的第一个括号所引用语句为语句1,第二个为语句2,以此类推。

12.所有查找内容:\0
这个指代搜索项里面所有内容。

13.标记表达式:\1 \2 \3 ……
这个配合第11条,第一个括号对应\1,第二个对应\2以此类推。

14.数字:\d
就是匹配0-9所有数字了,显然\d+就是匹配任意长度字符串了,不过个人习惯用[0-9]+代替,因为操作和变形更灵活。比如[0-9a-z]+就是任意字母数字串。

15.重复:{ }
{n}指重复n次,比如[a-zA-Z]{3}指任意三个字母连用的串;
{n,}指重复至少n次,比如[0-9]{4,}可以指任意大于等于一千的数,当然,如果你写上0123也能匹配上;
{n,m}指重复次数大于等于n,小于等于m。

16.转义:\
以上所提语句都有各自的特殊符号表示含义,那么我们如果只是想要查找他们的本身而不是其所代表的含义呢?
很简单,在该符号前面加\即可。比如正则直接搜索*会报错,搜索\*就可以了。以上几条其实已经把\的功能表示出来了,比如\d,\r,\n等已经不代表字母的本身了,实际上还有很多字母加\也会有别的含义,比如\t代表制表符,这里就不做介绍,因为做书一般用不到。

17.汉字的正则表达式:
这个比较常用。用两种形式皆可:[\x{4e00}-\x{9fa5}]或[\u4e00-\u9fa5]。

以上说了很多,相信大家已经有了一个直观的认识,另外切记,正则是搜索项而不是替换项,替换项只能是常规内容或是第13条那样的,正则符号如果写在替换项,那么符号本身是什么,就会被替换成什么。

活用正则可以节省很多时间,并收获到意想不到的效果。

比如某本书的章节目录是这样的:第十三卷 阡陌居 第894章 风筝出品
那么就可以这样匹配:第[一二三四五六七八九十零百千]+卷 .* 第[0-9]+章 .*
回复 使用道具 举报
感谢,刚学完这个一头雾水。
回复 使用道具 举报
正则表达式   干货,,已收藏  ,发散
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马