正则表达式你们应该都不陌生,可是给人的印象可能就是不那么高大上又很难理解、很难精通的这么一个玩意儿,并且适用范围又不是那么宽。就是这么一个感受有点鸡肋的东西,若是到了须要的场合而不会用,就会面临一种“前进是悬崖,后退是荒芜”的困境。
我最近正在作一些关于Html代码的解析工做,虽然手头上有jsoup这样好用的工具,仍是架不住世界上的技术人员代码风格变幻无穷,不免遇到不按套路出牌的,专门花一点时间系统的学习一下正则表达式确实颇有必要。
这里有同窗就要问了:网上不是有不少现成的例子么,匹配适用的语言,直接拿过来用不就行了?固然,这样作方便快捷,可是弊端也很明显,一是缺少原理背后的讲解,一旦找不到合适的例子就只能一筹莫展,这就是人们熟知的“鱼”和“渔”,二是网上的博客什么的也是人写的,也不必定适合复杂多变的状况,也不必定正确。因此,仍是决定深刻了解学习一下,写下这篇专栏记录学习经历。
注:学习使用的教材是余晟老师著《正则指引》(第二版),当前使用程序设计语言为Java,在学习中可能更多关注与Java相关的内容。正则表达式
在一对方括号 [ 和 ] 之间列出全部可能出现的字符,包括可见以及不可见的字符;例如:[123]
表示能够匹配一、二、3的单个字符。编程
若是能够匹配的字符有规律性而且范围比较大,好比0、一、二、三、四、五、六、七、八、9,表达式写成 [0123456789]
这样就显得复杂也不美观,因此引入符号“-”,使用 [x-y] 的形式表示在闭区间x到y范围内的字符,上式能够写成[0-9]
编程语言
[0-9a-zA-Z]
工具
在表达式中有特殊功能而不做为字符的一部分字符,称为元字符。好比前文讲过的:[ ] - 都是元字符,若是想要恢复它们原本的字符属性就要作一些特殊处理。先看通常状况,取消元字符特殊含义的操做叫作转义,操做是在表达式中的元字符前加反斜杠 。特殊状况就是表示范围的横线 - ,当其紧邻左方括号 [ 时就做为普通字符处理,其余状况都做为元字符表示范围。学习
一、横线 - 也支持反斜杠的转义,即[0-9]表示0、-、9三个字符。
二、右方括号 ] 不须要转义。编码
当须要表示的字符组范围很大,写起来不方便,而恰巧它的补集(全集指全部字符)方便表示,引出了排除型字符组[^…]
,表示在当前位置匹配一个没有列出的字符,请注意是“必须匹配一个没有出现的字符”,而不是“不要匹配列出的字符”。例如:设计
[^0-9][^0-9]
能够匹配“QQ”,但不能够匹配“Q”。code
常见的字符组简记法有\d
([0-9]
)、\w
([0-9a-zA-Z_]
)、\s
([\t\r\n\v\f]
)博客
`[0-9a-zA-Z]`能够写成`[\da-zA-Z]`
正则表达式也提供了上面三种经常使用简记法的排除型:\D
、\W
、\S
,这三种分别对应各自的补集(全集是指全部字符,即[dD]能够匹配任意字符,剩余两者同理)。程序设计
从新回顾1.3第一段话,当咱们所研究的问题要求咱们的全集不是全部字符,排除型字符组就显得不是那么的好用了。好比我须要匹配字母表第一、五、9个小写字母,把全部字符看做全集显然不合适,而把全部小写字母看做全集就比较合适,可是写成[b-df-hj-z]就比较复杂并且容易搞错,Java就容许使用逻辑与(&&,也能够理解为取交集)来解决这个问题,即写成:
[a-z]&&[^aei]
我所学习和说明的正则表达式是PCRE流派的,教材上还介绍了POSIX等其余流派的正则表达式,这里暂不做说明。
【预告】第二章量词