基础正则表达式详述

栏目: Perl · 发布时间: 6年前

内容简介:本文介绍基础正则表达式,没有示例(),只有总结和"解惑",如果想学习更强大、更完整的正则,可以参考:Perl正则超详细教程,特殊且常用的的组合正则表达式:需要解释清楚的是这些量词(也就是上面匹配的次数元字符)的特殊性:当使用了匹配多次的量词时(如匹配3-5次的

本文介绍基础正则表达式,没有示例(),只有总结和"解惑",如果想学习更强大、更完整的正则,可以参考:Perl正则超详细教程, grep -P 、ack都支持 Perl 正则,且很多需要使用到正则的服务软件一般都采用PCRE(如httpd、nginx、haproxy、proxysql),它和Perl正则几乎完全一致,作为运维人员,我觉得是有必要学上一学的。

基础正则

元字符:

  • . :匹配任意单个字符,但不能匹配换行符 \n
  • * :匹配前面那个字符0或多次
  • ? :匹配前面那个字符0或一次
  • + :匹配前面那个字符1次以上
  • {M,N} :匹配前面那个字符至少M,最多N次
  • {M,} :匹配前面那个字符至少M次,最多无限制
  • {,N} :匹配前面那个字符最多N次(最少当然是0次)。注意,perl正则不支持这种方式
  • {M} :匹配前面那个字符正好M次
  • 锚定:锚定的意思是匹配位置,而非匹配字符实体
    ^
    $
    

特殊且常用的的组合正则表达式:

^$
.*

需要解释清楚的是这些量词(也就是上面匹配的次数元字符)的特殊性:当使用了匹配多次的量词时(如匹配3-5次的 {3,5} ),且量词前面的字符有多种可能性(如中括号序列 [abc] ),那么量词的次数可以作用于任一字符。有些不好理解,但看示例就知道了:

[abc]{3,5}     # 表示abc任意字符都可以出现,比如全是a,或者ab同时出现,但总的出现次数为3-5次
.*          # 表示任一字符(除换行符),可以任意出现任意次数,它不表示a之后就必须全是a
.+          # 表示任一字符(除换行符),可以任意出现至少一次,它不表示a之后就必须全是a

另外, . 无法匹配换行符。可能你不太理解为什么需要匹配换行符,它主要用在:

/^a.*\nb.*/

中括号

中括号表示的是匹配任意一个,一般它和字符集的 排序 规则有关,不同 工具 采取的排序规则可能也不一样。

[abcd...]
[^abcd...]
[a-z]
[A-Z]
[0-9]

关于字母的排序:

  • perl中,A-Z排在a的前面,所以[A-z]表示所有大小写字母
  • grep中,A-Z排在z的后面,所以[a-Z]表示所有大小写字母
  • 还有些工具中,大小写的排序规则是aAbBcC...zZ,所以[a-C]表示aAbBcC共6个字母

字符类

是专门命名的中括号序列;除了字符类,还有等价类、排序类,但基本用不上,只用字符类。

  • [:alpha:] :匹配字母,等价于 [a-zA-Z]
  • [:digit:] :匹配数字,等价于 [0-9]
  • [:xdigit:] :匹配十六进制数,等价于 [0-9a-fA-F]
  • [:upper:] :匹配大写字母,等价于 [A-Z]
  • [:lower:] :匹配小写字母,等价于 [a-z]
  • [:alnum:] :匹配数字或字母,等价于 [0-9a-zA-Z]
  • [:blank:] :匹配空白,包括空格和制表符
  • [:space:] :匹配空格,包括空格、制表符、换行符、回车符等各种类型的空白
  • [:punct:] :匹配标点符号。包括: ! ' " ` # $ % & ( ) * + , . - _ / : ; < = > ? @ [ \ ] ^ { | } ~
  • [:graph:] :绘图类。包括:大小写字母、数字和标点符号。等价于 [:alnum:] + [:punct:]
  • [:print:] :打印字符类。包括:大小写字母、数字、标点符号和空格。等价于 [:alnum:] + [:punct:] +space
  • [:cntrl:] :控制字符类。在ASCII中,这些字符的八进制代码从000到037,还包括177(DEL)

需要注意的是,通常字符类在真正使用过程中,会再加上一个中括号,例如 [[:alpha:]] 。之所以如此,是因为这些字符类只是一种命名好的字符集合。例如 [:lower:] 对应的字符集合是a-z,而不是 [a-z] ,所以要想让其表示这些命名字符类中的任一字符,需要再加上一层括号 [[:lower:]] ,它才等价于 [a-z] 。可能会更有助于理解使用字符类的时候为什么要加两个中括号的例子是 [^[:lower:]] ,它表示不包含任何小写字母。

反斜线序列

不同的工具,同一工具不同的版本,支持的反斜线序列能力不同。以下列出了部分常见序列。

以下所说的单词,一般来说只包含数字、字母和下划线,即 [_0-9a-zA-Z]

以下几种反斜线序列,基本上所有工具都支持:

  • \b :匹配单词边界处的空字符
  • \B :匹配非单词边界处的空字符
  • \< :匹配单词开头处的空字符
  • \> :匹配单词结尾处的空字符
  • \w :匹配单词构成部分,等价于 [_[:alnum:]]
  • \W :匹配非单词构成部分,等价于 [^_[:alnum:]]

以下几种,有些工具不支持,但perl都支持:

  • \s :匹配空白字符,等价于 [[:space:]]
  • \S :匹配非空白字符,等价于 [^[:space:]]
  • \d :匹配数字,等价于 [0-9]
  • \D :匹配非数字,等价于 [^0-9]

由于元字符 . 默认无法匹配换行符,所以需要匹配换行符的时候,可以使用特殊组合 [\d\D] 来替换 . ,换句话说,如果想匹配任意长度的任意字符,可以换成 [\d\D]* ,当然,前提是必须支持 \d\D 两个反斜线序列。

分组捕获和反向引用

基础正则中,使用括号可以对匹配内容进行分组并暂时保存,分组后会有分组编号,可以使用反斜线加编号 \N 的方式反向引用这些分组。

分组编号的方式是从左向右计算括号数,无论如何嵌套,第一个左括号对应的分组一定是编号1,用 \1 来引用,第二个左括号对应的分组一定是编号2,用 \2 来引用,依此类推。

例如grep的分组捕获:匹配两个连续相同的字母。

echo "abcddefg" | grep -E "(.)\1"

可以认为分组就是变量赋值的过程。例如,上面示例的匹配过程如下:

1.匹配第一个字母a,放进分组,即赋值给变量(假设变量名为$1),即 $1="a" ,再继续执行正则表达式匹配过程的反向引用,它引用的是$1,于是表示第一个字母a后面还要是字母a,于是匹配失败。

2.匹配第二个字母b,放进分组,即 $1="b" ,再匹配后一个字母,于是匹配失败。

3.字母c同样如此。

4.匹配字母d,放进分组,即 $1="d" ,再匹配后一个字母,发现匹配成功,于是$1被保存下来。

5.已经匹配成功,于是结束。

对于只使用基础正则的工具来说,一般都只能引用 \1\9 共9个反向引用,最多自己额外提供一个所有表示匹配内容的反向引用(例如sed提供的 & )。对于超出10个的分组,使用基础正则的工具一般来说是无能为力的。

再者,基础正则仅仅只是将分组匹配到的内容捕获,在正则操作结束后就丢失。但对于一门完整编程语言来说,这远远不够,几乎所有编程语言(如perl/java/Python等)都会将正则的分组匹配内容保存为变量,使得可以在正则结束之后再次引用甚至修改它们。例如上面例子中分组捕获的字母d,如果换成perl,即使在这个匹配过程结束后,还是可以去引用这段分组。

二选一

  • pattern1 | pattern2 :匹配竖线左边,或者匹配竖线右边都算匹配成功

关于二选一的结构,几点需要说明:

ab|cd

在二选一结构种,两个反向引用问题的典型例子:

例如 a(.)|b\1 将无法匹配"ba",因为评估了左边就不会评估右边。

例如 ([ac])e\1|b([xyz])\2t 的左边能匹配aea或cec,但不能匹配cea或aec,右边能匹配bxxt或byyt或bzzt。但如果将 \2 换成 \1 ,即 ([ac])e\1|b([xyz])\1t ,将无法匹配b[xyz]at或b[xyz]ct,因为第一个分组括号在左边,无法参与右边的正则评估。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址: https://www.linuxidc.com/Linux/2018-10/154659.htm


以上所述就是小编给大家介绍的《基础正则表达式详述》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

应用Rails进行敏捷Web开发

应用Rails进行敏捷Web开发

Dave Thomas, David Hansson等 / 林芷薰 / 电子工业出版社 / 2006-7 / 65.00元

这是第一本关于Ruby on Rails的著作。 全书主要内容分为两大部分。在“构建应用程序”部分中,读者将看到一个完整的“在线购书网站” 示例。在演示的过程中,作者真实地再现了一个完整的迭代式开发过程,让读者亲身体验实际应用开发中遇到的各种问题、以及Rails如何有效解决这些问题。在随后的“Rails框架”部分中,作者深入介绍了Rails框架的各个组成部分。尤为值得一提的是本部分的后几章......一起来看看 《应用Rails进行敏捷Web开发》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具