学习正则表达式

字符组

普通字符组

字符组是一组字符,在正则表达式中,它表示“在同一个位置可能出现的各种字符”,其写法是在一对方括号[和]之间列出所有可能出现的字符,简单的字符组包括[ab]、 [314]、[#.?]等。

普通字符串匹配数字字符的正则表达式:

[0123456789]

范围字符组

正则表达式提供了-范围表示法(range),它更直观,能进一步简化字符组。所谓-范围表示法,就是用 麻烦,这样 就可以表示为确实比的形式表示 x 到 y 整个范围内的字符,省去一一列出的麻烦。 在字符组中,-表示的范围,一般是根据字符对应的码值(Code Point,也就是字符在对应编码表中的编码的数值)来确定的,码值小的字符在前,码值大的字符在后。因此[0-9] 是合法的,[9-0]会报错。

范围字符串匹配数字字符的正则表达式:

[0-9]

在字符组中可以同时并列多个-范围表示法,字符组[0-9a-zA-Z]可以匹配数字、大写 字母或小写字母

表示十六进制

[0-9a-fA-F]

字符串转义

在字符组中,如果要匹配的字符是特殊字符,就需要对特殊字符进行转义,比如要匹配字符组中的-,就需要对-进行转义,即\-。但是有时候却不需要转义。

如果要在字符组中匹配-,最好的办法是把-放在字符组的最前面或者最后面,这样就不需要转义了。比如,要匹配-,可以写成[0-9-]或者[-0-9]

同理,如果要字符组中匹配方括号,则需要在方括号前面加上反斜杠\进行转义,即[123\]567]如果要匹配[123]567,则正则表达式为\[123\]567],末尾的]不需要转义。

取反字符组

在字符组中,如果在第一个字符前面加上^,则表示取反,即不匹配字符组中的字符。比如,[^0-9]表示不匹配数字字符,[^a-z]表示不匹配小写字母。取反字符组必须匹配一个字符,如果不匹配任何字符,则会报错。

匹配0,9之外的数字

java

[^09]

^是正则表达式的元字符,只在[后面才表示取反,如果^不在[后面,匹配时不需要转义。 [0^12][\^012]是等价的,都表示匹配字符0^12。但是后者写起来会麻烦一些。

字符组简记法

对于常用的字符组,正则表达式提供了简记法,比如\d表示数字字符,\w表示单词字符,\s表示空白字符。

字符组简记法完整表示
数字字符\d[0-9]
单词字符\w[a-zA-Z0-9_]
空白字符\s[ \t\n\v\f\r]

\w 匹配单词字符,即字母、数字或下划线。如果只要匹配字母和数字,可以使用[a-zA-Z0-9]

简记法也可以和普通字符组、范围字符组、取反字符组混合使用。

用在普通字符串内部

[\da-zA-Z]表示匹配数字字符或字母字符。

用在取反字符组内部

[^\w]表示匹配非单词字符。

\D, \W, \S 的使用

\D\W\S分别表示非数字字符、非单词字符、非空白字符。他们与\d\w\s形成互补关系。

匹配所有字符

[\s\S],\s表示空白字符,\S表示非空白字符,因此[\s\S]表示所有字符。同理,[\d\D][\w\W]表示所有字符。

如果在字符组中使用了简记法,则最好不要出现范围字符组,比如[\d-a],简记法和范围字符组混用会导致不可预知的结果。

字符组运算

有部分编程语言提供了字符组运算的支持。不同的编程语言支持的字符组运算符不同,比如Java中的字符组运算符是&&,而Go中的字符组运算符是-

我们要实现在字母中排除元音字母的效果,按照之前的写法,需要写成[bcdfghjklmnpqrstvwxyz]或者[b-df-hj-np-tv-z],如果使用字符组运算,可以写成[a-z&&[^aeiou]] 。在这里,&&表示字符组运算符,&&前面的字符组表示基础字符组,&&后面的字符组表示排除字符组,即基础字符组中排除排除字符组中的字符。两者取交集,得到最终的字符组。

POSIX 字符组

以上的字符组定义都属于PCRE的流派,PCRE是Perl语言的正则表达式引擎,它的正则表达式语法和Perl语言的正则表达式语法基本一致,在大多数语言中得到了支持。 POSIX字符组是POSIX的流派,POSIX 是一个操作系统标准,它定义了操作系统的接口和行为,比如Linux/Unix操作系统都是基于POSIX标准的。 它的语法和普通字符组不同,但是功能和普通字符组一样。POSIX字符组的语法是[:name:],其中name 是字符组的名称。他主要的的使用场景是Linux/Unix环境下各种工具(比如grep、sed、awk等)的正则表达式。

POSIX字符组说明PCRE
[:alnum:]字母或数字[a-zA-Z0-9]
[:alpha:]字母[a-zA-Z]
[:blank:]空白字符[ \t]
[:cntrl:]控制字符[\x00-\x1F\x7F]
[:digit:]数字[0-9]
[:graph:]图形字符[!-~]
[:lower:]小写字母[a-z]
[:print:]可打印字符[ -~]
[:punct:]标点符号[!-/:-@[-`{-~]
[:space:]空白字符[ \t\n\v\f\r]
[:upper:]大写字母[A-Z]
[:word:]单词字符[a-zA-Z0-9_]
[:xdigit:]十六进制数字[0-9a-fA-F]

不同语言对POSIX字符组的支持情况不同,视具体情况而定。