这里简单总结以下Perl中正则表达式的用法
Perl中模式匹配符的形式如下:
该式是布尔表达式,返回true
或者false
。其中,m
是操作符,dl
是模式的限定符(指定模式的起始和结束),modifiers
是可选的,可用于改变模式的用法。最常见的限定符是斜杠/
,当使用/
作为限定符时,m
可以省略。当模式中需要用到/
(例如UNIX路径:usr/users/sebesta
),我们可以使用其他限定符,但此时m
不可省略,例如m~pattern~
。
模式中的字符分为三类:
转义序列,例如\t
和\cC
(Control+C),可以出现在模式中,并匹配自身。元字符仅当在前面插入\
时才可以匹配自身。元字符有:\
|
(
)
[
]
{
}
^
$
*
+
?
.
,其中有的字符仅在特定的上下文中有特殊的意义。
默认参与匹配的字符串是$_
,因此可以直接使用如下的结构:
模式中出现的空格也是普通字符,匹配自身。例如:
句号匹配除了换行符外的任意字符。例如:
字符类是一组字符,其中的任意一个字符可以匹配目标字符。例如:
短横线-
可用于表示一个范围内的字符。例如:
如果-
出现在字符类的末尾,则仅表示一个普通字符,匹配自身。如果你需要在字符类中的其他地方指定普通字符-
,则需要在前面添加反斜杠\
。
有时,指定不属于某一范围的字符更加方便,我们可以在字符类的最左端添加^
:
有些字符类是很常用的,它们有预定义的缩写:
缩写 | 等价模式 | 匹配 |
\d | [0-9] | 一个数字 |
\D | [^0-9] | 一个非数字字符 |
\w | [A-Za-z_] | 一个单词字符 |
\W | [^A-Za-z_] | 一个非单词字符 |
\s | [ \r\t\n\f] | 一个空白符 |
\S | [^ \r\t\n\f] | 一个非空白符 |
示例如下:
模式中也可以包含变量。例如:
Perl中提供了4种量词:*
+
?
{m,n}
。量词紧跟在字符、字符类或者小括号括上的子模式后面,用以指定重复的次数。
量词 | 意义 |
{n} | 重复n次 |
{m,} | 重复至少m次 |
{m,n} | 重复至少m次,且不超过n次 |
其他量词是以上形式的缩写,*
相当于{0,}
,+
相当于{1,}
,?
相当于{0,1}
。
量词匹配引出了匹配过程的分析:
?
来启用最小匹配示例如下:
模式 | 字符串 | 匹配子串 |
/m/ |
Tommie | 左边的m |
/m*/ |
Tommie | T左边的空字符串 |
/m*i/ |
Tommie | mmi |
/.*Bob/ |
Bob sat next to the Bobcat and listened to the Bobolink | Bob sat next to the Bobcat an listened to the Bob |
/Fred+/ |
Freddie’s hot dogs | Fredd |
/Fred+?/ |
Freddie’s hot dogs | Fred |
/Bob.*Bob.*link/ |
Bob sat next to the Bobcat and listened to the Bobolink | 其中第一个.* 匹配” sat next to the Bobcat and listened to the “ |
析取(Alternation)通过|
来指定,它相当于编程语言中的逻辑或。例如:
析取结构从左往右逐个尝试匹配,所以/Tom|Tommie/
永远不会匹配右边的”Tommie”。在字符类中没有必要使用析取操作符,例如[belly|belts|bells]
相当于[belyts]
,这可能并不是你想要的结果。
要正确地使用各种模式操作符,必须了解其优先级。
操作符 | 优先级 |
括号 | 最高 |
量词 | 较高 |
字符类 | 较低 |
析取 | 最低 |
例如:/#|-+/
匹配一个#号或者一个或多个减号;而/(#|-)+/
匹配一个或多个#号或者一个或多个减号。
锚用于匹配字符串中的特定位置,而不是匹配其中特定的字符或字符串。其中^
匹配字符串中第一个字符前面的位置,即表示字符串的开头;$
匹配字符串中最后一个字符后面的位置,即表示字符串的结尾;\b
匹配字母字符(\w
)和非字母字符(\W
)之间的位置,可用于匹配某个不属于另一单词中的单词。注意^
符号仅在位于模式最左端或字符类最左端时具有特殊意义,其他情况下都是匹配自身的普通字符。
示例如下:
Perl中可以使用=~
让某个字符串尝试匹配某模式,返回布尔值,表示是否成功匹配。也可使用!~
来判断是否不能成功匹配,结果与=~
相反。
模式的末尾可以带上修饰符,它要么会改变模式的解释方式,要么会改变模式匹配的工作方式。
符 | 意义 |
i | 忽略大小写 |
m | 输入字符串被当作多行文本来处理,此时^ 匹配所有换行符的前面位置,$ 匹配所有换行符的后面位置 |
s | 输入字符串被当作单行文本来处理,此时. 会匹配所有字符,包括换行符 |
o | 当模式中出现scalar变量,默认情况下,此模式在每次使用时都会重新编译,执行开销较大;而当确定变量的值恒定不变时,可使用此修饰符通知Perl无需重复编译此模式 |
x | 允许在模式中包含空白符且它们不会被解释,使得该模式与去掉这些空白符后的模式等价。这里空白符包括以# 开头的行注释,从而我们可以给复杂模式添加注释 |
某些时候,我们需要在模式里引用已经匹配了的部分子串,这可以通过用括号括上需要引用的部分,并使用\1
,\2
等隐式变量来引用对应的部分子串。其对应关系由左括号出现的顺序决定,最左边出现的左括号对应\1
,然后第二个左括号对应\2
等等。如果要在模式外部引用已匹配的子串,则可使用$1
,$2
等隐式变量,对应规则与\1
,\2
等一样。并且,在list上下文中,模式操作符的返回值就是$1
,$2
等等。
Perl中可以使用$&
或$MATCH
(使用use English
时)来获得上次匹配中成功匹配的部分。
示例如下:
Perl包含了一些正则表达式的扩展,形如(?xPattern)
,其中x
为单个字符或双字符,确定了使用哪种类型的扩展。
x | 功能 |
: | 取消引用该括号匹配的子串,节省匹配运行开销 |
= | 正预测先行断言,确保某模式后紧跟该断言中的模式,且断言中模式匹配的子串不计入匹配结果并参与后续匹配过程 |
! | 逆预测先行断言,确保某模式后不紧跟该断言中的模式,且断言中模式匹配的子串不计入匹配结果并参与后续匹配过程 |
<= | 正回顾后发断言,确保某模式前紧跟该断言中的模式,且断言中模式匹配的子串不计入匹配结果 |
<! | 逆回顾后发断言,确保某模式前不紧跟该断言中的模式,且断言中模式匹配的子串不计入匹配结果 |
split函数的第一个参数可以使用正则表达式,从而更灵活地切割字符串。
Perl中可以用正则表达式来替换文本的内容,形式如s dl Pattern dl New_string dl Modifiers
。其中,dl是分隔符,不加修饰符modifiers时,最常见的形式为s/Pattern/New_string/
。而修饰符除了前面提到的一些可以在这里使用外,我们还可以用g
来表示替换文本中所有可以匹配该模式的子串,用e
表示替换部分是需要解析的表达式。替换操作返回成功替换的子串的个数,当然仅当使用修饰符g
时才会出现多个子串被替换。
参考书籍:《A Little Book on Perl》, Robert W. Sebesta, Prentice Hall.