由于最近接手一个代码使用正则表达式匹配location做不同环境的配置,由是又双叒叕看不懂正则,第N次去看正则相关的材料,所以觉得还是应该知其所以然,系统学习一下,并做下总结。
图书材料 :《学习正则表达式》
What
正则表达式是描述一组字符串特征的模式,用来匹配特定的字符串。
—— Ken ThompsonRegular Expression的“Regular”一般被译为“正则”、“正规”、“常规”。此处的“Regular”即是“规则”、“规律”的意思,Regular Expression即“描述某种规则的表达式”之意。 —— 维基百科
这个网站很方便做正则的测试:http://www.regexpal.com/
How
下面讲解一下常用的正则语法
正则表达式语言由两种基本字符类型组成:原义(正常)文本字符和元字符。
原义示例: 正则表达式:hello,对hello world的匹配结果为 hello world
元字符使正则表达式具有处理能力。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
简单点:元字符不参与匹配,其表示的特殊意义作为规则匹配
元字符
元字符 | 作用 | 示例 | 匹配结果(用超链接样式做为匹配标志) |
---|---|---|---|
. | 匹配任意字符 | . | aBc.:x |
\ | 转义符下一个字符标记为 一个特殊字符 或一个原义字符 或一个后向引用 或一个八进制 |
\. 其余后面分别详细讲解 |
aBc.:x匹配真正的. |
| | 或操作 | [3|5] | 12345 |
^ | 行起启锚位符 非,不匹配指定字符或字符组 |
^1 [^12] |
1211 31245 |
$ | 行结束锚位符 | 1$ | 1211 |
? | {0,1}匹配前面字符 0次或1次 | 21? |
2 21 (无论是否有1都会被匹配) |
* | {0,n} 0次或多次 | 21* |
2 21 211111 |
+ | {1,n} 1次或多次 | 21+ | 2(没有1时不会被匹配) 21 211111 |
{} | 量词或代码块 | a{3} a{2,5} |
aaabaa (3个a,2个不会被匹配) aaabaa (2到5个a会被匹配) |
[] | 字符组(字符集:一类字符的集合) | [abc] 字符范围[a-z] |
dabec a-z任意小写字母 同理有:[A-Z],[0-9],[a-zA-Z] |
() | 分组,子表达式,优先 | ([ab])x\1 |
axa bxb axb \1指代前面的[ab]这个子表达式的匹配值 |
- | 分隔线 | - | - |
以下一些由\开头的特殊意义字符 | 注意有时需要"\\"来转义为\与后面的字符配合成新的意义使用 | ||
\b | 单词边界,表示单词的起始 | \baaa\b \baaa |
baaa aaa aaab baaa aaa aaab |
\B | 非单词边界 | \Baaa\B | baaa aaa baaab aaab |
\d | 数字 | \d | 124SA236SFa |
\D | 非数字 | \D | 124S<:">A236SFa |
\s | 匹配任何空白字符,包括空格、制表符、换页符等等。 | \s | 等价于[ \f\n\r\t\v] (后续介绍) |
\S | 匹配任何非空白字符 | \S | 等价于[^\f\n\r\t\v] |
\w | 匹配包括下划线的任何单词字符。 | 等价于[A-Za-z0-9_] | |
\W | 匹配任何非单词字符。 | 等价于[^A-Za-z0-9_] | |
tip | 大小写表示的含义相反 | ||
\f | 匹配一个换页符 | 等价于\x0c和\cL | |
\n | 匹配一个换行符 | 等价于\x0a和\cJ | |
\r | 匹配一个回车符 | 等价于\x0d和\cM | |
\t | 匹配一个制表符 | 等价于\x09和\cI | |
\v | 匹配一个垂直制表符 | 等价于\x0b和\cK | |
tip | 多用于支持正则查找替换的编辑器 | ||
\xn | 匹配n,其中n为字符的十六进制值。十六进制转义值必须为确定的两个数字长。 | \x41 \x401 |
A 等价于\x04&1正则表达式中可以使用ASCII编码。 |
\num | 标识一个八进制转义值或一个向后引用。 如果\n之前至少n个获取的子表达式,则n为向后引用[1]。 否则,如果n为八进制数字(0-7),表示字符的进制值。[2] |
(.)\1 \101 |
匹配两个连续的相同字符aa bb ccda A |
\uxxxx | 字符的Unicode值 | \u00A9 | © 版权符号 |
优先级 | 符号 |
---|---|
最高 | \ |
高 | ( )、(?: )、(?= )、[ ] |
中 | *、+、?、{n}、{n,}、{m,n} |
低 | ^、$、经\转义的 |
最低 | | |
其它
贪婪型,懒惰型元字符
* 和+,{n,} 贪婪型元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止的。
*?,+?,{n,}? 懒惰型元字符(上面的加?后缀) 适可而止
例:字符串 123456
3\d+匹配结果:123456 3及其以后的数字全被匹配,多多益善
3\d+?匹配结果:123456 3及其后的一个数字被匹配,适可而止前后查找 有时候需要正则表达式标记要匹配的文本的位置(而不仅仅是文本本身)
- (?=) 正向前查找 其实就是一个以?=开头的子表达式
- (?<=)正向后查找 查找出现在匹配文本之后的字符(js不支持)
- (?!) 负向前查找 指的是不与给定模式相匹配的文本 不常用
- (?<!)负向后查找 同上
例:.{2}(?=(abc)) 结果 xxxabc (abc前面的两个字符)
(?<=al).*(?=xl) 结果alcccxl (al与xl中间的字符 )
实例
掌握上面的这些基础理论,应该就可以应付正则的大部分使用场景,能看能写。
- 一些元字符的java使用示例:RegularExpression.java
最全的常用正则表达式大全——包括校验数字、字符、一些特殊的需求等等
希望看完我这篇文章,能看得懂这些常用的正则表达式(反正我是看懂了)IDEA 正则替换实例
小结
正则的语法还是比较简单易懂的,只是用的频率不是那么高,所以容易忘,所以做下笔记,以后忘了看自己写的东西终归是更容易理解,也希望对大家有帮助。