Java中的正则表达式(1)

正则表达式(Regular Expressions)可不是Java的专利,很多的语言像Perl,Python,PHP,Ruby等等都支持正则表达式,正则表达式是字符串处理的利器,它是一种描述字符串模式的式子,一个正则表达式的核心价值就是匹配一个字符串。各个语言实现的正则表达式引擎并不完全相同,Oreilly出版的《精通正则表达式》是讲解正则表达式的经典教程。这里只是总结下Java中的正则表达式的相关知识,Java中的正则表达式功能是通过java.util.regex包中的两个类来实现的:Pattern类,定义了封装了正则表达式的对象;Matcher类,它定义了封装了一个状态机的对象,这个状态机可以使用一个给定的Pattern对象搜索一个特定的字符串。这个包里还定义了PatternSyntaxException类,如果编译正则表达式创建Pattern对象时发现语法错误,将抛出异常。正则表达式也是个字符串,一般会把它封装到一个Pattern对象里,某些简单的情况下,完全可以不用regex包,只用String类的matches()就可以判断该字符串是否和正则表达式匹配。例如:

"one piece".matches("one.*");//true 

 

使用java中的正则式基本上很简单:

(1)把一个包含正则表达式的字符串传给Pattern类的静态方法compile()来创建一个Pattern对象。

(2)然后通过调用Pattern对象的matcher()方法,并把要被搜索的字符串作为实参以获得一个Matcher对象。

(3)调用Matcher对象的find()方法来搜索字符串。

(4)如果找到了这个模式串,可以查询Matcher对象以找出该模式串在字符串的什么位置以及与其匹配的相关的其他信息。

 

上面这4步是《Java2 入门经典》---Ivor Horton  这本书里讲的,这些步骤指引了我们怎么来学正则表达式:1.最核心的东西就是正则表达式的编写,也就是说掌握正则表达式语法来写出想匹配的字符串的模式,比如说要匹配一个email地址,怎么来写正则式。2. 弄明白matcher(),find(),compile()等方法的作用,其实就是查API,看这些方法参数是啥,返回值是啥,作用是啥。3.关于正则表达式的编程都是按照某些步骤来做的,按要求步步为营即可。现在学习套路很明确了,简单的说就是:掌握语法—>弄懂方法—>遵循步骤。

 

下面先说第一步,Java中正则表达式的语法,这里就是理清语法的脉络,具体的语法都是点到为止,因为baidu,维基等搜索引擎就可以直接搜到关于正则式语法的详细讲解。正则表达式的语法要素有以下这些:常规字符,字符类(字符集合),通配符,量词,边界匹配符,运算符,组,标志序列。结合例子来帮助理清正则表达式语法的脉络。

比如说有一个字符串"0310handan",我们要写一个正则式来描述这个字符串,最简单的怎么做呢?就写0310handan(查API会看到方法compile的参数是String regex,正则表达式是以字符串的形式给出来的,但就其本身来说并不是字符串,这里为了突出正则表达式的语法特性,所以都不带引号),这就是常规字符的用处,常规字符按其字面含义匹配。要都这么干的话这个正则表达式就是一一映射了,一个字符串对应一个正则表达式,我们说正则表达式是描述字符串的利器,这就意味着两点:1.一个正则表达式能描述多个甚至是无限多个字符串,这反映了它描述功能强大。2.一个字符串可以被表示成多个正则表达式,这反映了它的灵活。因为既强大又灵活所以叫做“利器”。接下来的语法特性都是为达到这两点来服务的。匹配的过程就是一个个的字符在匹配,比如说"0310handan",写成正则表达式就是10个单元项,依次对应着0,3,1,0,h,a,n,d,a,n,加入什么样的语法特性可以让正则式里的一个单元项来匹配很多的字符呢,很自然的想法就是用一个单元项来表示很多存在某个共性的字符的集合,这个单元项叫做字符类,比如说[xyz]可以匹配x,y或者z,[^xyz]匹配x,y,z之外的任何字符,[a-z]匹配所有小写字母,\d可以匹配数字0-9,等等。Java正则表达式API提供了丰富的预定义字符类来表述这种想法,常用的有以下几种,\d,\D,\w,\W,\s,\S。这几个挺好记忆的,因为太常用了所以记法简单,Java还提供了具有如下通用形式的大量的字符类,\p{name},name指定类的名称,以下是几个示例:

\p{Lower}   包含小写字母

\p{Upper}   包含大写字母

\p{Punct}    包含所有的标点符号

不管记法怎样,这些统统都表示一个单元项,用来匹配一个字符,还遗漏一个“大人物”,就是通配符,写出来就是一个点号".",为啥说它是大人物呢,它能匹配所有字符。

 

到了这里虽然长见识了,但是也有疑问了,表述能力是强了,不过写起来还是很麻烦呀,以"0310handan"为例,还是要写出来10个单元项,只是每个单元项有了多种可选择的写法而已,比如可以写成...\d.....\p{Lower} ,但是写出来的岂不是更长了,不由得感叹这正则表达式白学了,好麻烦。该介绍正则表达式中一个化繁为简的语法特性了,就是量词,具体地说分为贪婪量词,胁迫量词,占有量词。量词用处很大并且使用简单,它决定了一个单元项将匹配多少次,简单的说可以把多个相同的单元项合并,所以上面的写法也就是从语法上说能匹配"0310handan",实际中不可能这么干,因为要尽量把每个字符都表示成统一的形式,这样再用个量词就可以写的简洁些,比如说用这个式子来匹配该字符串:\d\d\d\d\w\w\w\w\w\w,应用量词后就可以写成: \d+\w{6} 量词如下所示:

+  匹配1次或多次 

*  匹配0次或多次

? 匹配0次或1次

这3个很常用,不过只要这仨的话够用不?很明显,这都没有指定具体的量是多少,用{num}可以指定次数,比如说x{2}匹配"xx"。现在够了么,固定次数显得不够灵活,还要有指定最小次数和最大次数的{min,max},这里不指定max也可以,例如x{2,}可以匹配"xx","xxx","xxxx",等等。量词的种类现在似乎够用了。其实还没介绍完,到此为止谈论的都是贪婪量词,那么胁迫量词和占有量词是咋回事儿呢?后面再做解释。 

 

转载于:https://www.cnblogs.com/op20100420/archive/2010/04/25/1719602.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值