陈某某的网络日志

活到老学到老,学习无止境

0%

正则表达式笔记

简介

正则表达式(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])$

正则规范

有许多的语言和工具都支持正则表达式,但是它们支持的标准不尽相同。

  1. POSIX规范:

    • BRE(基本正则表达式): (){} 等元字符要加转义符,不支持反向引用\1,\2,不支持量词+,?
    • ERE(扩展正则表达式): (){} 无需加转义,量词+,?可以直接使用
      如linux下的工具基本采用POSIX规范,sed/grep 默认使用的为BRE,grep -P使用下面的PCRE,awk默认使用的为 ERE
      其实现在纯粹的BRE用的比较少了,GNU其实对这些工具都作了一定的扩展。
  2. PCRE(Perl Compatible Regular Expression)
    PCRE可以认为是事实上的标准,来自于Perl,很多对正则的支持均移植于PCRE,常见的字符组\d,\w,\s均来自于PCRE。

参考资料