对于正则表达式一向了解不多,假期期间随着《正则表达式必知必会》快速学习了一下正则表达式的基本使用,在此记录一下。
正则表达式语法笔记
常用元字符
元字符 | 作用 |
---|---|
. | 换行符外任意字符 |
\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 ](最后有个空格) |
要注意,[]内出现的的元字符对应字符,不按照元字符处理,不需要要转义,如“.”、“$”等
重复匹配
表达式 | 作用 |
---|---|
+,[]+ | 匹配前面字符/集合的一次或多次,贪婪 |
*,[]* | 匹配前面字符/集合的零次或多次,贪婪 |
?,[]? | 匹配前面字符/集合的零次或一次,等价于{0,1} |
+? | +的懒惰情况 |
*? | *的懒惰情况 |
{n},[]{n} | 字符或集合出现 n 次 |
{n,m},[]{n,m} | 字符或集合出现 n 到 m 次 |
{n,},[]{n,} | 字符或集合出现 n 到无穷次/至少 n 次,贪婪 |
{n,}?,[]{n,}? | {n,},[]{n,}的懒惰情况 |
关于贪婪和懒惰,可见例子:
1 | <B>AK</B> and <B>HI</B> |
使用
1 | <B>.*</B> |
将匹配到
1 | <B>AK</B> and <B>HI</B> |
而懒惰形式
1 | <B>.*?</B> |
将匹配到
1 | <B>AK</B> |
和
1 | <B>HI</B> |
边界
表达式 | 作用 |
---|---|
\b | 单词边界,相当于 \w 和 \W 之间的位置 |
\B | 非单词边界,即 字母数字下划线之间 或 非字母数字下划线之间 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
(?m) | 加在最前,使 ^ 和 $ 匹配行内字符串开头和行内字符串结尾。ps:不一定每种语法都适用 |
\A | 同 ^,但 (?m) 对其无效 |
\Z | 同 $,但 (?m) 对其无效 |
回溯引用
表达式 | 作用 |
---|---|
() | 括号内的作为一个子表达式,其中的元字符对应字符要匹配时需要转义,如”.” |
\1 | \1、\2 等是回溯引用,\1 将回溯引用第一个子表达式,\2 回溯第二个,以此类推(\0 在多种语法中表示整个正则表达式) |
例如,使用回溯引用
1 | <[Hh]([1-6])>.*?</[Hh]\1> |
来匹配 html 1 到 6 级标题。
另外注意,使用
1 | .*? |
而不是
1 | .* |
是为了避免过度匹配,比如,使用
1 | <[Hh]([1-6])>.*</[Hh]\1> |
将在
1 | <h1>test1</h1><h2>test2</h1> |
中匹配到
1 | <h1>test1</h1><h2>test2</h1> |
前后查找
表达式 | 作用 |
---|---|
?= | 向前查找,要作为子表达式使用 |
?<= | 向后查找,要作为子表达式使用 |
?! | 负向前查找,要作为子表达式使用 |
?<! | 负向后查找,要作为子表达式使用 |
例如,对于
1 | http://matian.connorma.cn |
使用向前匹配
1 | \w+(?=:) |
的匹配结果为
1 | http |
使用向后匹配
1 | (?<=://).* |
的匹配结果为
1 | matian.connorma.cn |
向前查找和向后查找可以起来,比如对上例,
1 | (?<=://)[\w\.]*(?=\.cn) |
将匹配到
1 | matian.connorma |
对于负向前/后查找,比如,
1 | 30 |
若要匹配所有金额数值,可以使用
1 | (?<=\$)\d+ |
将匹配到
1 | 59 |
若要匹配所有非金额的数字,可以使用
1 | \b(?<!\$)\d+\b |
将匹配到
1 | 30 |
这里要注意,如果不使用 \b,而使用如下的表达式
1 | (?<!\$)\d+ |
匹配结将是
1 | 30 |
条件(或)
对 OR 运算符“|”,
使用时注意
有优先级问题,如 19|20\d{2},匹配 19,或者 20xx 的四位数字;(19|20)\d{2},匹配 19xx 或者 20xx 的四位数字。
表现出短路,如 (((\d{1,2})|(1\d\d)|(2[0-4]\d)|(25[0-5])).){3}((\d{1,2})|(1\d\d)|(2[0-4]\d)|(25[0-5])) 意在匹配 ip 地址,但是好像,经测试,| 在正则表达式中,也表现出了短路的特性,会导致最后一段出现类似 255 只匹配到 25 的情况,而最后一段出现 256 时,将匹配到 25。\b(((\d{1,2})|(1\d\d)|(2[0-4]\d)|(25[0-5])).){3}((\d{1,2})|(1\d\d)|(2[0-4]\d)|(25[0-5]))\b 看起来更合理。
其他嵌入条件暂时没看。
常用表达式
匹配空白行(linux + windows)
1
[\r]?\n[\s]\*[\r]?\n
匹配 Email
1
(\w+\.)*\w*@(\w+\.)+[A-Za-z]+
匹配 URL 地址
1
[a-zA-z]+://[^\s]*
匹配 ip 地址
1
((?:(?:25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d?\d))