【从零开始】正则表达式从入门到应用1

正则表达式大家应该都不陌生,但是给人的印象可能就是不那么高大上又很难理解、很难精通的这么一个玩意儿,而且适用范围又不是那么宽。就是这么一个感觉有点鸡肋的东西,如果到了需要的场合而不会用,就会面临一种“前进是悬崖,后退是荒芜”的困境。
我最近正在做一些关于Html代码的解析工作,虽然手头上有jsoup这样好用的工具,还是架不住世界上的技术人员代码风格千变万化,难免遇到不按套路出牌的,专门花一点时间系统的学习一下正则表达式确实很有必要。
这里有同学就要问了:网上不是有很多现成的例子么,匹配适用的语言,直接拿过来用不就好了?当然,这样做方便快捷,但是弊端也很明显,一是缺乏原理背后的讲解,一旦找不到合适的例子就只能束手无策,这就是人们熟知的“鱼”和“渔”,二是网上的博客什么的也是人写的,也不一定适合复杂多变的情况,也不一定正确。所以,还是决定深入了解学习一下,写下这篇专栏记录学习经历。
注:学习使用的教材是余晟老师著《正则指引》(第二版),当前使用程序设计语言为Java,在学习中可能更多关注与Java相关的内容。

1字符组

在一对方括号 [ 和 ] 之间列出所有可能出现的字符,包括可见以及不可见的字符;例如:
[123]
表示可以匹配1、2、3的单个字符。

1.1字符组的范围表示

如果可以匹配的字符有规律性并且范围比较大,比如0、1、2、3、4、5、6、7、8、9,表达式写成
[0123456789]
这样就显得复杂也不美观,所以引入符号“-”,使用 [x-y] 的形式表示在闭区间x到y范围内的字符,上式可以写成
[0-9]

【注意】:-范围表示法必须遵循ASCII编码的先后顺序,即上式不可写作 [9-0] ,而一些令人困惑的表达式也尽量不要使用,比如 [0-z] 因为该式涵盖了在ASCII编码表中从0到z的全部字符(不仅仅只有数字和小写字母)。如果想要表示多个范围,比如匹配数字、大写字母和小写字母,表达式可以写作

[0-9a-zA-Z]

1.2元字符与转义

在表达式中有特殊功能而不作为字符的一部分字符,称为元字符。比如前文讲过的:[ ] - 都是元字符,如果想要恢复它们本来的字符属性就要做一些特殊处理。先看一般情况,取消元字符特殊含义的操作叫做转义,操作是在表达式中的元字符前加反斜杠 。特殊情况就是表示范围的横线 - ,当其紧邻左方括号 [ 时就作为普通字符处理,其他情况都作为元字符表示范围。

【注意】

1、横线 - 也支持反斜杠的转义,即[0-9]表示0、-、9三个字符。
2、右方括号 ] 不需要转义。

1.3排除型字符组

当需要表示的字符组范围很大,写起来不方便,而恰巧它的补集(全集指所有字符)方便表示,引出了排除型字符组[^…] ,表示在当前位置匹配一个没有列出的字符,请注意是“必须匹配一个没有出现的字符”,而不是“不要匹配列出的字符”。例如:

[^0-9][^0-9]

可以匹配“QQ”,但不可以匹配“Q”。

【注意】紧跟在 ^ 之后的 - 不是一个元字符!而^自身也是元字符,当且仅当^紧跟[时,否则表示它作为字符的含义。

1.4字符组简记法

常见的字符组简记法有\d[0-9])、\w[0-9a-zA-Z_])、\s[\t\r\n\v\f]

【注意】w可以匹配下划线,不等价于[0-9a-zA-Z]。另外字符组简记法可以单独出现,也可以使用在字符组中,如
`[0-9a-zA-Z]`可以写成`[\da-zA-Z]`

正则表达式也提供了上面三种常用简记法的排除型:\D\W\S,这三种分别对应各自的补集(全集是指所有字符,即[dD]可以匹配任意字符,剩余二者同理)。

【再次注意】第一,使用字符组简记法最好不要出现单独的 - ;第二,上面描述的简记法都是针对ASCII编码而言的;第三,字符组简记法不止这三种,还有其他(也可能根据不同的编程语言衍生出新的简记法),等遇到了再说。

1.5字符组的运算

重新回顾1.3第一段话,当我们所研究的问题要求我们的全集不是所有字符,排除型字符组就显得不是那么的好用了。比如我需要匹配字母表第1、5、9个小写字母,把所有字符看作全集显然不合适,而把所有小写字母看作全集就比较合适,但是写成[b-df-hj-z]就比较复杂而且容易搞错,Java就允许使用逻辑与(&&,也可以理解为取交集)来解决这个问题,即写成:

[a-z]&&[^aei]

我所学习和说明的正则表达式是PCRE流派的,教材上还介绍了POSIX等其他流派的正则表达式,这里暂不作说明。

【预告】第二章量词

你可能感兴趣的:(正则表达式,java,入门教程,应用)