JobPlus知识库 互联网 互联网运营 文章
正则表达式(Regular Expression)-(2)字符匹配

原义字符

顾名思义,我们可以使用原义字符的字面意义来匹配字符串。如在字符串“Jack is a boy”中查找单词“boy”,直接使用正则表达式:

`boy`

注意,原义字符是区分大小写的,`boy`和`Boy`是两个不同的表达式。

特殊字符

特殊字符是区别于原义字符的另一种字符,这些字符往往不代表其本来的意思。而是赋予了其特殊的含义,通常也称为元字符。这些特殊字符有以下几个:

`\`,`^`,`$`,`.`,`|`,`?`,`*`,`+`,`(`,`)`,`[`,`{`

这些字符不代表其本身的含义。 如果要匹配元字符的字面含义,如匹配字符“+”,需要用转义字符进行转义`\+`。要匹配“1+2=3”,正则表达式应该为:

`1\+2=3`

如果不进行转义,正则表达式:

`1+2=3`

表达式里面的`+`用于修饰字符“1”,表示字符“1”可以出现一次或多次。可以匹配字符串“12=3”、“112=3”或“11112=3”等等。

大多数情况下,元字符是不能独立存在的。比如使用`+`或`+1`是会报错的。 

在一些正则表达式引擎里面,还支持`\Q...\E`表达式。所有在`\Q`和`\E`中间的字符都被解释成普通字符。如`\Q1+2=3\E`,匹配的就是字符串“1+2=3”,这里的"+"就表示普通的“+”字符。`\E`不是必须的,表达式`\Q1+2=3\E`和`\Q1+2=3`是一样的意义。

编程语言和元字符

如果对元字符进行编程,则要特别注意,不同语言对字符串的处理。特别要记住的就是编程语言的编译先于正则表达式执行。

 如在C++里面,我们要匹配字符串“C:\Test”。如果我们将正则表达式写成“C:\\Test”。C++先对程序进行编译,编译器将“\\”转义成“\”,所以这个字符串经过编译器后变成了:

`C:\Test`

这显然不是我们的原意。所以在C++里面,应该写成"C:\\\\Test",经过编译后才是:

`C:\\Test`

非打印字符 

正则表达式还可以匹配非打印字符。非打印字符有:

`\t`表示制表符

`\r`表示回车符

`\n`表示换行符

`\a`表示响铃符

`\e`表示退出符号

`\f`表示换页符号

`\v`表示垂直制表符。部分解释器`\v`可以匹配任意垂直符号,包括垂直制表符、表符、换行符等。

 注意,在Windows中用\r\n表示换行,在UNIX中用\n。 

字符编码

除了上述常用的非打印字符外,还能直接使用字符编码来表示匹配。

用`\c`和A~Z字母表示控制支付。`\c`字母“c”为小写,后面跟26个大写英文字母A到Z,表示Control+A到Control+Z。例如,匹配换行符“\r”(ASCII码13)。可以用正则表达式:

`\cM`

控制字符Control+M即为换行符。在`\c`后如果不跟字母A到Z,不同的解释器处理不同。有些会报错,有些会转化成ASCII码来执行。

有些解释器支持16进制编码匹配Unicode字符。例如,匹配换行符“\r”(ASCII码13)。可以用正则表达式:

`\u000D` 

有些解释器也会写成`\x{000D}`。16进制编码匹配Unicode字符,以`\u`开头,`\u`后面为4个十六进制编码字符。如果位数不够,需要在`\u`后面用0补齐。

如果仅支持8位编码,还可以用`\x`来表示。例如,匹配换行符“\r”(ASCII码13)。可以用正则表达式:

`\x0D`

16进制编码匹配ASCII码字符,以`\x`开头。`\x`后跟2个十六进制编码字符。如果位数不够,需要在`\x`后用0补齐。

有些解释器也支持8进制的编码规则。例如,匹配换行符“\r”(ASCII码13或15(8进制))。可以用正则表达式:

`\015` 或 `\0015`

8进制编码匹配ASCII码字符,有些解释器以`\0`开头,有些则不需要。8进制编码需要3个八制编码字符。如果位数不够,需要在`\`或`\0`后用0补齐。

非打印字符和编程语言

在部分编程语言中,对非打印字符的解释是不一样的。由于编程语言先于正则表达式执行,所以要注意一下,那些经过编程语言后,字符串可能会被改变。

如,在C语言中,字符串“Jack is a boy \n”。这里的“\n”在C语言编译完会被判断为新的换行。所以,传递给正则表达式引擎的内容为“Jack is a boy”和一个新行。

字符集

字符集是字符的集合,用于匹配若干个字符的其中一个字符。字符集用方括号`[]`来表示。

字符集经常用于查找不确定的某个字符。例如,需要查找单词“apple”或“Apple”,首字母可能是大写的也可能是小写的。可以使用使用正则表达式:

`[Aa]pple`

`[Aa]`表示首字母可能是"A"或“a”。

字符集还可以用`-`号来表示范围。例如,需要匹配字符串里面16进制的字符串“0xFF”,正则表达式为:

0x[0-9A-F][0-9A-F]

其中的`[0-9A-F]`表示的是“0”到“9”和“A”到“F”共16个字符。需要注意的是,`-`号只能在字符集里面使用,而且前后必须是可以取得其范围的两个字符,如`[-9]`或者`[a-9]`这种表达方式是错误的。

负值字符集

负责字符集是指,匹配字符集之外的所有字符。负值元字符用`^`表示。例如,我们要匹配非数字字符,正则表达式为:

`[^0-9]`

元字符`^`必须跟在`[`后面。用元字符`^`包括了一切字符,包括非打印字符,如`\r`和`\n`等。所以,不匹配换行符,需要将表达式改成:

`[^0-0\r\n]`

字符集里的特殊字符

在字符集里面,只有`\^-`三个特殊字符可用。其他的特殊字符均按原义字符处理。如,要匹配“*+?”,正则表达式为:

`[*+?]`

在字符集里对多数特殊字符都无需进行转化。如果要匹配特殊字符“\^-”,则需要用转义字符`\`进行转义,正则表达式为:

`\\\^\-`

注意,也有正则表达式解释器只支持`-^`两个特殊字符,不支持`\`。在这些解释器里面,无法对任何字符进行转义。

特殊字符需要出现在对应的地方,否则可能会被解释成原义字符或直接报错。如,正则表达式`[-9]`或`[a^]`,这里的`-`和`^`没有在规定位置出现,所以,会被当成字符"-"和“^”进行匹配,或者直接报错。

字符集简写

一些常用的字符集还可以进行简写。例如:

`\d`  匹配一个数字字符,等价于 [0-9]。

`\D` 匹配一个非数字字符,等价于[^0-9]。

`\w` 匹配一个包括下划线的单词字符,等价于[a-zA-Z0-9_]

`\W` 匹配一个包括下划线的非单词字符,等价于[^a-zA-Z0-9_]

`\s`  匹配一个空白字符,等价于[\f\n\r\t\v]

`\S` 匹配一个非空白字符,等价于[^\f\n\r\t\v]

.(点)符号

`.`符号可以匹配除了换行符`\n`元字符之外的所有字符。

不同的解释器对`.`符号的解释也不一样,所以在使用过程中,也要注意每个解释器的具体应用。

`.`作为一个常用的符号,在使用过程中需要特别注意。如,匹配日期:

`\d\d.\d\d.\d\d`

这个表达式匹配的,显然这里的`.`并不匹配字符“.”,所以表达式是错误的。为了正确的匹配,我们可以对`.`进行转义,如:

`\d\d\.\d\d\.\d\d`

或者,使用字符集。比如日期分隔符可以是 “.-/”其中一个,上述表达式可以写成:

`\d\d[.-/]\d\d[.-/]\d\d`

`.`在字符集里面是不生效的。

换行

多数解释器支持`.`符号,但是不同的系统对“换行”的解释是不一样的。对于UNIX系统,来说''\n"就是换行。而所有脚本只认“\n”作为换行符,而不人其他的字符如“\r”等。所以对于UNIX来说,正则表达式解释器是没问题的。但是,Windows是以"\r\n"作为换行符,但是这并不影响正则表达式的使用。脚本在Windows读取字符串的时候会自动将"\r\n"转换成“\n”,而在写文件的时候将“\n”写成“\r\n”。

字符串边界选择

正则表达式除了能匹配某个字符,还能匹配某个位置。

`^` 匹配字符串开始的位置。在多行模式(multiline mode)下,还可以匹配换行符后的位置。

`$`匹配字符串结束的位置。在多行模式(multiline mode)下,还可以匹配换行符前的位置。

如果需要匹配字符串“Lesson N”,作为课程编号一般都独立一行显示,而不会出现在文章中间。正则表达式为:

`^Lesson [1-9]$`

正则表达式可以匹配字符串“Lesson 1”。但是不能匹配字符串“Read the Lesson 1.”。因为“Lesson 1”前面不是字符串开始位置,后面也不是字符串结束位置。

`^`和`$`并不是匹配特定的一个字符,而是指一个位置而已。对于表达式`^a`来说,表示在"a"之前没有任何字符了,“a”是字符串的第一给字符。类似的,表达式`a$`表示在“a”后已经没有任何字符的了,“a”是字符串的最后一个字符。

多行模式

在多行模式下,`^`和`$`可以匹配字符串换行的位置。如,需要匹配字符串“abc\ndef”。那么`^`可以匹配“a”之前的位置与"\n"和“d”之间的位置。而`$`匹配“c”和“\n”之间的位置与"f"之后的位置。

注意,`^`和`$`并不匹配换行字符“\n”,而是匹配一个位置而已。

有些正则表达式解释器需要明确开启多行模式,才可以支持多行模式。在非多行模式下。使用正则表达式`c$`可以匹配字符串"abc"里的字符串“c”,而不能匹配字符串“abc\n”里的字符串“c”。因为“abc\n”字符“c”后是“\n”而不是字符串结束位置。

有些解释器用`\A`和`\Z`来代替`^`和`$`表示字符串开始和结束位置。

单词边界

单词边界和字符串边界类似,是一个确定位置的符号。单词边界用“\b”表示。单词边界可以理解成:

1. 如果字符串的第一个字符为单词字符,则字符串开始之后的位置。

2. 如果字符串的最后一个字符为单词字符,则字符串结束之前的位置。

3. 在一个单词字符和非单词字符之间的位置。

对于什么是单词字符,每个解释器有自己的解释。多数解释器将字符集`\w`作为单词字符,其他为非单词字符。

在字符串“Hello World!”中,`\b`可以匹配“H”之前的位置,“o”和空格之间的位置,空格和“W”之间的位置,"d"和“!”之间的位置。如果需要匹配单词“Hello”,正则表达式为:

`\bHello\b`

`\B`表示非单词边界,作用跟`\b`相反,匹配任何一个在单词字符中间的位置。如需要匹配“Hello”里面的字符“ll”,正则表达式为:

`\Bll\B`




如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

¥ 打赏支持
154人赞 举报
分享到
用户评价(0)

暂无评价,你也可以发布评价哦:)

扫码APP

扫描使用APP

扫码使用

扫描使用小程序