目录
前言
学自《正则表达式必知必会》。一边学习一边动手尝试,并对自己的想法进行验证,是个挺有意思的过程。
本文正则表达式测试采用的链接: 正则表达式在线测试
一、特殊字符
字符 | 匹配 |
---|---|
. | 任意单字符(一般来说.不匹配换行符) |
+ | 匹配一个或多个字符(或字符集合) |
* | 匹配0个或多个字符(或字符集合) |
? | 匹配0个或1个字符(或字符集合) |
\ | 转义字符 |
^ | 非 |
\r\n | “回车+换行”组合 |
[] | 字符集 |
{} | 重复次数 |
() | 子表达式 |
特别的,
元字符 | 说明 |
---|---|
\d | 任何一个数字字符,等价[0-9] |
\D | 任何一个非数字字符,等价[^0-9] |
\w | 任何一个字母数字字符(大小写均可)或下划线, 等价[a-zA-Z0-9_] |
\W | 任何一个非字母数字字符或下划线,等价[^a-zA-Z0-9_] |
\s | 任何一个空白字符,等价[\f\n\r\t\v] |
\S | 任何一个非空白字符,等价[^\f\n\r\t\v] |
1.1举例
?匹配0个或1个
{}重复次数
{3} 重复3次
{2,4} 最少重复2次,最多重复4次——引申:?相当于{0,1}
{3,} 至少重复3次,即必须重复3次或更多次
1.2小应用
利用{3,}找出了整数部分3位数以上的金额。
注意防止过度匹配
● 想拿到标签之间的内容,匹配时出现的问题:
1.3贪婪型元字符和懒惰型元字符
常用的贪婪型元字符和他们的懒惰型版本
贪婪型元字符 | 懒惰型元字符 |
---|---|
* | *? |
+ | +? |
{n,} | {n,}? |
要根据具体情况来选“贪婪型”或“懒惰型”元字符!!
此例子利用懒惰型元字符进行修改:
二、位置匹配
2.1单词边界\b
\b匹配的是这样一个位置,这个位置位于一个能够用来构成单词的字符(字母、数字、下划线,也就是与\w匹配的字符)和一个不能用来构成单词的字符(也就是与\W想匹配的字符)之间。
注意:\b匹配且只匹配一个位置,部匹配任何字符。\bcat\b匹配到的字符串长度为3。
2.2不匹配单词边界\B
例如,利用\B查找前后都有多余空格的连字符。
2.3字符串边界^和$
^是几个有着多种用途的元字符之一。当它出现再一个字符集合里(被放在[和]之间)并紧跟着左方括号[的后面时,它才能发挥“求非”的作用。
^匹配一个字符串的开头位置,$匹配一个字符串的结尾位置
2.4分行匹配模式(?m)
分行匹配模式将是的正则表达式引擎把行分割符当作一个字符串分隔符来对待。
在分行匹配模式下,^不仅匹配正常的字符串开头,还将匹配行分隔符(换行符)后面的开始位置(这个位置是不可见的);$类似。
(?m)必须在整个模式最前面.
exp:匹配代码注释行。
警告:有许多正则表达式实现不支持(?m) (这个结果可能是这个原因吧)
三、子表达式
子表达式必须用(和)括起来。如有必要,子表达式可以嵌套使用。
exp:找19XX年和20XX年的年份
Tip:
| 操作符是把位于它左边和右边的两部分都作为一个整体来看待的,它会把模式19|20\d{2}解读成19或20\d{2},使用()把19|20归为一个子表达式。
把必须匹配的情况考虑周全并写出一个匹配结果符合预期的正则表达式很容i,但把不需要匹配的情况也考虑周全并确保它们都被排除在匹配结果以外往往困难得多。
四、回溯引用:前后一致匹配
4.1找出重复的词
在搜索某个词第二次出现时,这个单词必须是已知的。当(\w+)匹配到of时,\1也匹配单词of,当当(\w+)匹配到are时,\1也匹配单词are。
回溯引用指的是模式的后半部分引用在前半部分中定义的子表达式。
\1代表模式里的第一个子表达式,\2代表模式里的第二个子表达式;以此类推。
4.2匹配标签内容
利用懒惰型元字符:
利用回溯,使一级标题只和一级标题匹配。
注意:不同的正则表达式在实现回溯引用的语法方面往往有着巨大的差异。
回溯引用只能用来引用模式里的子表达式(用()括起来的正则表达式片段)
提示:回溯引用匹配通常从1开始计数(\1、\2)。在许多实现里,第0个匹配(\0)可以用来代表整个正则表达式。
注意:子表达式通过它们相对位置来引用,虽受到普遍的支持,但存在严重不足,一旦相对位置发生变化,原来模式也许不能再完成原来的工作。为弥补这一不足,一些比较新的正则表达式实现还支持“命名捕获”:给子表达式起个名字,用名字引用。
4.3回溯在替换操作中的应用
替换操作需要两个正则表达式:一个用来给出搜索模式,一个用来给出匹配文本的替换模式。
回溯引用语法在不同的正则表达式实现里有很大差异。
4.4用来进行大小写转换的元字符
元字符 | 说明 |
---|---|
\E | 结束\L或\U转换 |
\l | 把下一个字符转换为小写 |
\L | 把\L到\E之间的字符全部转换为小写 |
\u | 把下一个字符转换为大写 |
\U | 把\U到\E之间的字符全部转换为大写 |
五、前后查找
5.1向前查找
以?=开头的子表达式,需要匹配的文本跟在=后面。
提示:有些正则表达式文档使用术语“消费”来表述“匹配和返回文本”的含义。在向前查找里,被匹配的文本不包含在最终返回的匹配结果里,这被称为“不消费”。
exp.提取协议名
子表达式(:)正确匹配到了:并消费了这个字符——:
注意:向前查找(和向后查找)匹配本身其实是有返回结果的,只是这个结果的字节长度永远是0而已。因此,前后查找操作有时也被称为零宽度 匹配操作。
5.2向后查找
操作符?<=
?<=与?=的具体使用方法大同小异:它必须用在一个子表达式里,而且后跟要匹配的文本。
exp.提取金额(利用向后查找提取$之后的数字)
5.3前后查找结合
5.4对前后查找取非
向前查找和向后查找通常用来匹配文本,目的是为了确定将被返回为匹配结果的文本的位置。这种用法被称为正向前查找和正向后查找。“正”指的是寻找匹配的事实。
前后查找还有一种不太常见的用法 叫作负向前查找。
各种前后查找操作符
操作符 | 说明 |
---|---|
(?=) | 正向前查找 |
(?!) | 负向前查找 |
(?<=) | 正向后查找 |
(?<!) | 负向后查找 |
exp.查找非金额数字(此处注意\b的作用)
六、嵌入条件
6.1回溯引用条件
只在一个前面的子表达式搜索取得成功的情况下才允许使用一个表达式。
语法是(?(backreference)true-regex)
否则 表达式只在给定的回溯引用不存在(也就是条件没有得到满足)时才被执行,语法是
(?(backreference)true-regex|false-regex),这个语法接受一个条件和两个将分别在则会个添加得到满足和没有得到满足时执行的子表达式。