简介
正则表达式(Regular Expression ,re,regex)。个人理解就是是一种匹配的模式(pattern),可以用来匹配符合pattern的字符串。本身就是用特殊的字符串和语法规则来书写。常见语言c#,java,python,vb,php等都支持,基本语法类似,但细节上和支持的元字符有所不同。Linux下的文本处理工具sed,awk(gawk),grep都会用到正则表达式。
元字符
字符组
- [] 表示匹配这一系列字符集合中的任一个
- \d 数字,等价于[0-9]
- \w 数字,字母 ,等价于[0-9a-zA-Z]
- \s 空字符 等价于[ \t\r\n\v\f] 第一个是空格
- -是在[]是不用转义的,表示范围,其它元字符必须用\转义
- ^在[]表示非(不是开始位置),[^0-9]表示非数字
量词
- {m,n} 之前的元素出现最少m次,最多n次
- * 任意次, 等价于{0,}
- + 最少一次,等价于{1,}
- ? 0次或1次,等价于{0,1}
量词默认都是贪婪匹配,有时要懒惰匹配,需要在后面加?
其它元字符
- . 匹配除\n之外的任意字符
- ^ 字符串开始位置
- $ 结尾位置
- \b 单词边界
分组
- (exp) 括号里面的叫分组,也叫子表达式,子模式,可以看做一个整体。
- 分组可以后向引用, 从\1,\2…开始。
环视(look around)
类型 | pattern |
---|---|
Positive Lookahead | /pattern/(?=exp) |
Positive Lookbehind | (?<=exp)/pattern/ |
Negative Lookahead | /pattern/(?!exp) |
Negative Lookbehind | (?<!exp)/pattern/ |
这些()里的分组都是不捕获的,可以理解为自定义的边界,只匹配位置。
这几个名字不好记,翻译成中文叫啥的都有(环视,预查,零宽断言)。
简单记忆:=是要匹配的(肯定),!是不能匹配的(否定),<是从右往左(逆序,反向,behind),没有< 是正则默认的从左往右(顺序,正向,ahead)。
注:以肯定顺序环视为例,常见的写法是 /pattern/(?=exp)
表示要匹配的pattern右边是子表达式匹配的位置。
但也可以这么用 (?=exp)/pattern/
文本: jack2007jac
正则 (?=jack2007)jack
可以匹配出jack
用jack(?=2007)
一样匹配出jack
Mode
匹配模式(这里不是pattern),可理解为 匹配时有哪些选项。包括: 不区分大小写,单行(DOTALL)模式 等。
结构是(?modifier),写在整个表达式的开头处。
(?i) 表示不区分大小写
(?s) 单行模式(点号通配),此时.可以匹配\n
(?m) 多行模式(和单行模式没关系),影响的是^$,匹配行的开始和结束
Unicode
匹配unicode代码值:如”我”
python: \u6211
php: \x{6211}
匹配中文: [\u4e00-\u9fff] (CJK统一表意符号)
Unicode属性
三种属性:
1.Unicode Property 功能,是标点,字母,符号? 而不关心是哪种语言的字符。\p{n}表示各种书写系统中的数字。
2.Unicode Block 所属代码区块,如控制字符和基本拉丁语\p{InBasic_Latin}, \u0000-\uFFFF 一共有105个区块。
3.Unicdoe Script 书写系统,是英文,中文,阿拉伯文?如 \p{Han}表示汉语(中文字符)
结构写法都是 \p{property},部分编程语言不支持。python的标准库re不支持, perl,php支持。
正则实例:
含义 | 正则表达式 |
---|---|
手机号码(非严格) | 1\d{10} |
匹配素数个长度的字符 | ^(?!(..+)\1+$) 解释:(..+)\1+ 表示两个及以上的重复出现2倍以上,即不是素数,?!是Negative Lookahead,整个表达式就是开头到最后不是非素数长的,即能匹配的就是素数个长度的字符串 |
IPV6 | ^(([0-9a-fA-F]{1,4}):){7}([0-9a-fA-F]{1,4})$ |
IPV4 | ^((2[0-4]\d|25[0-5]|1[0-9]{2}|[1-9]\d|[0-9])\.){3}(2[0-4]\d|25[0-5]|1[0-9]{2}|[1-9]\d|[0-9])$ |
正则规范
有许多的语言和工具都支持正则表达式,但是它们支持的标准不尽相同。
POSIX规范:
- BRE(基本正则表达式):
(){}
等元字符要加转义符,不支持反向引用\1,\2,不支持量词+,? - ERE(扩展正则表达式):
(){}
无需加转义,量词+,?可以直接使用
如linux下的工具基本采用POSIX规范,sed/grep 默认使用的为BRE,grep -P使用下面的PCRE,awk默认使用的为 ERE
其实现在纯粹的BRE用的比较少了,GNU其实对这些工具都作了一定的扩展。
- BRE(基本正则表达式):
PCRE(Perl Compatible Regular Expression)
PCRE可以认为是事实上的标准,来自于Perl,很多对正则的支持均移植于PCRE,常见的字符组\d,\w,\s均来自于PCRE。
参考资料
- regular-expressions 这个网站的有相当全面的正则表达式的知识,例子,参考。
- 常用正则表达式
- JavaScript Regular Expression Visualizer
- 正则表达式30分钟入门教程
- RegexGolf 一个re挑战网站
- regular expressions 101 这个网站可以检查正则表达式匹配时会不会出现问题,会给出匹配步数,时间等。
- 《正则指引》余晟 著