一个完整的正则表达式是由元字符和其他“文字”构成的,单个元字符就是正则表达式的最小单元,丰富的元字符提供强大的描述能力。我把正则表达式看成一种独立处理功能。那么在不同环境(Windows、MacOS…)、语言(.NET、Java、Python、Perl、PHP、MySQL、MSSQL、Ruby…)上面它会有很些差异,比如:字符串、字符编码、匹配模式。

一、字符串

这里的字符串是指正则引擎接收的字符串,我们知道一串字符串是用一对双引号标注,反斜线是元字符,但是在不同语言上面它们要表达同一个元字符有区别的。

JAVA:

Pattern regex = Pattern.compile("\\d", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE | Pattern.MULTILINE);

C#:

Regex regexObj = new Regex(@"\d", RegexOptions.IgnoreCase | RegexOptions.Multiline);

不同之处是\\d和\d的区别。至少C#看起来更简洁一点(@代表字符串是原生字符串,这种方式PHP同样也支持,当然还有更多)。

二、字符编码

字符编码是一种写明的共识,它规定不同数值的字节应该如何解释。

由于正常情况下不需要人工干涉所以我对这一节只是做一个了解而已。懒啊···· 😥

三、匹配模式

许多正则引擎都支持多种不同的模式,它们规定了正则表达式应该如何解释和应用。

我觉得我还是整理一下我常用的语言(C#)单独深入讨论。

常用的元字符和特性

以下是我用大量时间去整理出来,我针对.NET的一张表格,算是做为我个人的手册之一:

描述
字符表示法 单词分界符 \b、退格字符 \b、警报 \a、ASCII Escape \e、进纸符 \f、换行符 \n、回车符 \r、制表符 \t
字符组相关
  • [a-z]和[^a-z]普通字符组:它表示肯定断言也就是说必须匹配一个字符。[0-9]和[0123456789]速度上是一样的,我尝试在.NET平台下面做速度测试[0-9]表示法略胜一筹。
  • .点号:匹配任何字符的字符组。
  • 字符组简记法:
    1. \w:单词中的字符等价于[a-zA-Z0-9_],支持Unicode。
    2. \W:非数字等价于[^\w]
    3. \d:数字等价于[0-9]
    4. \D:非数字等价于[^\d]
    5. \s:空白字符等价于[空格\f\n\r\t]
    6. \S:非空白字符等价于[^\s]
  • 反向引用
锚点、零长度断言 锚点、零长度断言并不会匹配实际的文本,而是寻找文本中的位置。




  • ^、\A:匹配字符串起始位置
  • $、\Z:匹配字符串结束位置,也可以匹配字符串结尾的换行符
  • \z:只匹配字符串的末尾,不考虑任何换行符
  • \b、\B:匹配字符串的某些位置,开始和结束都用\b表示(\B:表示非单词分界符)。.NET单词分界符等于\w,PS:所有正则引擎都不会对单词进行语意分析。
  • 顺序环视(?=…)、(?!…);逆序环视(?<=…)、(?<!…):正常情况下用得比较少,但是我得专门一篇来复习它,至少我觉得它是非常棒。
分组、捕获、条件判断、控制
  • 捕获/分组括号:(…)、\1、\2…
  • 仅用于分组的括号:(?:…)
  • 命名捕获:(?<Name>)
  • 多选结构:…|…
  • 条件判断:(?if then|else)非常有趣应该单独说明。恩恩。
  • 量词:
    1. {n,m}:m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次
    2. *:匹配零次或多次
    3. +:匹配一次或多次
    4. ?:匹配零次或一次
注释和模式修饰符
  • 模式修饰符:(?i)
    i 不区分大小写 RegexOptions.IgnoreCase
    s 点号能匹配任何字符 RegexOptions.Singleline
    x 宽松排列和注释模式 RegexOptions.IgnorePatternWhitespace
    m 多行模式 RegexOptions.Multiline
    n 关闭(…)的捕获功能,只有(?<name>…)能够捕获 RegexOptions.IgnoreCase

参考资料

  1. 各种工具之正则表达式语法比较(转自永恒蓝哲
  2. 正则表达式