正则表达式中的元字符及含义

Sep 25, 2017


概述


metacharacters被我硬译为元字符, 其实我也不知道应该叫什么比较准确. 其实质为在正则表达式中表示一些特殊含义的字符组合被称作metacharacters. 例如$特指行尾.


详情


\

\用于赋予后面紧跟的字符一个特殊的意义的字符, 例如$表示行尾, \$表示美元符号.

^

^用于表示行首, 例如^L表示以L作为首字母的行.

注意: ^不能匹配嵌入在字符串中的行(紧跟在\n后面开始的新一行), 例如if (line1\nLine2 ~ /^L/)

上面的条件语句会返回一个假值. 上面的写法是awk语法.

$

$用于表示行尾, 类似于^. 同样不能匹配嵌入在字符串中的行尾.

``if (line1\nLine2 ~ /$1/) ... 该表达式返回值为false

.

.用于表示任意单个字符, 包括换行符. 例如.P表示匹配任意一个后面跟有P字符的字符.

注意: 在严格的POSIX模式的正则表达式中, .不能匹配NUL. NUL代表空字符, 该字符的每一位都是0.

[…]

[...]被称作括号表达式, 用于表示匹配方括号中的任意字符. 例如:[UFO]可以匹配U,F,O中的任意一个字符.

括号表达式中也可以使用一些特定的正则表达式. 具体可以使用的表达式形式可以从[…]中可以使用的表达式中找到

[^…]

[^...]被称作补码括号表达式, 这个表达式的格式必须是将^紧跟在[字符的后面. 用于表示匹配不在方括号中的任意字符. 例如:[^UFO]用于匹配不为U,F,O的任意字符.

|

|被用于指定一个替代的正则表达式, 等同于我们说的或关系. |在正则表达式的操作符中的优先级最低. 例如:^P|[awk]表示可以匹配以P字符开头的字符串, 或者任意部位包含有a,w,k中某一个字符的字符串.

(…)

(...)被用于对表达式分组, 即可以将一系列的表达式视为一个正则表达式. 和|一起使用来关联两个不同的表达式. 例如:@(samp|code)\{[^}]+\}用于匹配包含样式@samp{不是'}'的任意字符}或者@code{不是'}'的任意字符}.

上面的示例中的\{[^}]+\}表示一对花括号{}中含有至少一个不是}的字符.

*

*用来匹配*前面的正则表达式出现的任意次数(0次或者多次). 例如:ph**前面的出现的正则表达式为h, 所以会匹配一个字符p和后面跟着的任意次数个的h, 当然也可以只是一个p.

通过两点去理解*的工作方式:

  1. *只会去匹配任意次数的符合他前面的那个正则表达式形式的内容. 例如:ph*中的h. 为了让*可以匹配更大数量的字符, 可以使用(...). 例如:(ph)*就会匹配包含有0个或者多个ph字符的字符串. 比如ph,phphphph等.

  2. *会匹配尽可能多的符合他前面要求的正则表达式形式的内容. 例如ph*可以匹配phhhhhhhhhhhhhhooey字符串中所有的h.

+

+*的作用类似. 区别仅在于+必须匹配符合他前面的正则表达式形式的内容至少一次. 例如:ph+会匹配p字符和后面的所有h. 但是不能匹配只包含一个p字符的形式.

?

?*的作用类似. 区别仅在于?会去匹配他前面的正则表达式的内容一次或者0次. 例如:ph?只能匹配p或者ph这两种形式.

{n}, {n,}, {n,m}

在小括号内有一个或者两个数字, 并且前面的数字要小于右面的数字的这种形式的正则表达式被叫做间隔表达式.

  1. 如果括号内只有一个数字{n}, 表示该表达式匹配符合他前面的那个正则表达式形式的内容重复n次的字符串. 例如:p{3}会匹配字符串ppp

  2. 如果括号内的数字有两个{n,m}, 表示该表达式匹配符合他前面的正则表达式形式的内容重复n次到m次之间的字符串. 例如:p{3,5}会匹配字符串{ppp}, {pppp}, {ppppp}.

  3. 如果括号内之后一个数字且后面跟着一个,格式为{n,}, 表示该表达式会匹配符合在他前面出现的正则表达式形式的内容重复了至少n次的字符串. 例如:p{3,}会匹配一个包含有至少三个连续p的字符串中所有的p.

注意: 低版本的gawk程序不支持间隔表达式. 所以正则表达式中如果需要使用{或者}时, 可以不用去转义. 但是高版本的以及兼容了间隔表达式. 所以为了更加方便于跨平台建议只要在正则表达式中出现了{或者}一般都加上转义符号\.


小结


在POSIX类型的表达式中, 如果在*,+,?之前没有添加其他的正则表达式的话, 那这些操作符就代表自己本身. 但是在非POSIX类型的正则表达式中如果在这些操作符的前面没有加其他的正则表达式的话就会报错.


参考文献



上一篇博客:MySQL的子查询中排序
下一篇博客:方括号表达式中可以使用的表达式