原义字符
顾名思义,我们可以使用原义字符的字面意义来匹配字符串。如在字符串“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`
登录 | 立即注册