正则表达式总结(python)
正则表达式(称为RE,或正则,或正则表达式模式)本质上是嵌入在Python中的一种微小的、高度专业化的编程语言,可通过 re 模块获得。正则表达式用于对字符串进行操作,最主要的为:匹配字符串、修改字符串。
匹配字符:
元字符:这类字符拥有特殊含义,并且不匹配自己,相反它们表示应该匹配一些不同的东西,或者通过重复它们或改变它们的含义来影响正则的其他部分。
元字符的列表:. ^ $ * + ? { } [ ] \ | ( ) 。首先“[”和”]”, 它们用于指定字符类,它是你希望匹配的一组字符。 可以单独列出字符,也可以通过给出两个字符并用 '-' 标记将它们分开来表示一系列字符。 例如,[abc] 将匹配任何字符 a、b 或 c; 这与 [a-c] 相同,它使用一个范围来表示同一组字符。其次,最重要的元字符是”\”,反斜杠后面可以跟各种字符,以指示各种特殊序列,也用于转义所有元字符,可以通过反斜杠来移除它们的特殊含义,如:\[或\\。
\d
匹配任何十进制数字;这等价于类 [0-9]。
\D
匹配任何非数字字符;这等价于类 [^0-9]。
\s
匹配任何空白字符;这等价于类 [ \t\n\r\f\v]。
\S
匹配任何非空白字符;这相当于类 [^ \t\n\r\f\v]。
\w
匹配任何字母与数字字符;这相当于类 [a-zA-Z0-9_]。
\W
匹配任何非字母与数字字符;这相当于类 [^a-zA-Z0-9_]。
|
或者“or”运算符。 如果 A 和 B 是正则表达式,A|B 将匹配任与 A 或 B 匹配的字符串。 | 具有非常低的优先级,以便在交替使用多字符字符串时使其合理地工作。
^
匹配行的末尾,定义为字符串的结尾,或者后跟换行符的任何位置。:
\A
仅匹配字符串的开头。 当不在 MULTILINE 模式时,\A 和 ^ 实际上是相同的。
\Z
只匹配字符串尾。
\b
字边界。 这是一个零宽度断言,仅在单词的开头或结尾处匹配。 单词被定义为一个字母数字字符序列,因此单词的结尾由空格或非字母数字字符表示。
编译正则表达式
正则表达式被编译成模式对象,模式对象有各种操作的方法,例如搜索模式匹配或执行字符串替换。
>>> import re
>>> p = re.compile(“ab*)
>>> p
re.compile()也接受一个可选的flags参数,也叫做编译标志,用于启用各种特殊功能和语法变体。
应用匹配模式对象有以下几种方法与属性
以上的方法若匹配成功,会返回一个匹配对象,这包含匹配的相关信息:起始和终结位置、匹配的子串及其它。匹配对象实例的方法与属性:
分组:通常用于将正则分成几个子组来解析字符串,这些子组匹配不同的感兴趣组件,分组由元字符”(“,”)”来标记,它们将包含其中的表达式组合在一起,并且可以使用重复限定符重复组的内容;用”(“,”)”表示的组也捕获它们匹配的文本的起始和结束索引;这可以通过将参数传递给group(),start(),end(),span()。组从0开始编号,这表示整个正则。
非捕获和命名组:有时候会想要使用组来表示正则表达式的一部分,但是对检索组的内容不感兴趣,这时可以通过使用非捕获组来显示表达这个事实(?:…)
>>> m = re.match(“([abc])+”,”abc”)
>>> m.groups()
(‘c’,)
>>> m = re.match(“(?:[abc])+”,”abc”)
>>> m = groups()
()
而命名组不是通过数字引用,而是可以通过名称引用组,(?P<name>..)name是改组的名称,命名组的行为与捕获组完全相同,并且将组与名称关联
修改字符串:
除了针对静态字符串执行搜索,正则表达式通常也用于以各种方式修改字符串,有如下方法
.spilit(string[,maxsplit=0]):可以通过传递maxsplit的值来限制分割的数量。
>>> p = re.compile(r’\w+)
>>> p.split(‘This is a test,short and sweet ,of split().’)
[‘This’,’is’,’a’,’test’,’short’,’and’,’sweet’,’of’,’split’,’’]
>>> p.split(‘This is a test,short and sweet ,of split().’,3)
[‘This’,’is’,’a’,’test,short and sweet,of split().’]
搜索和替换:找到模式的所有匹配项,并用不同的字符串替换它们。Sub()接受一个替换值,可以是字符串或函数,也可以是要处理的字符串。
.sub(replacement,string[,count=0])
返回通过替换replacement替换string中正则的最左边非重叠出现而获得的字符串。如果未找到模式,则string将保持不变。
可选参数count是要替换的模式最大的出现次数;count必须是非负整数。
>>> p = re.compile(‘(blue|while|red)’)
>>> p.sub(‘colour’,’blue socks and red shoes’)
‘colour socks and colour shoes’
>>> p.sub(‘colour’,’no colours at all’)
(‘no coulours at all’,0)
在使用正则表达式中遇到的问题:
- match()函数与search()使用不当:
在使用模式对象进行匹配字符串时,通常使用match()函数或search()函数进行匹配,不过由于对函数的使用不当,有时候得到的结果并不是最终的结果。
Match()函数只检测RE是不是在string的开始位置匹配,而search()会扫描整个string查找匹配,会扫描整个字符串并返回第一个成功的匹配。因此,match()函数只有在0位置匹配成功的时候返回,不在开始位置匹配成功就会返回None.
如:
>>> print(re.match(‘super’,’superstition’).span())
(0,5)
>>> print(re.match(‘super’,’insuperable’))
None
>>> print(re.search(‘super’,’superstition’).span())
(0,5)
>>> print(re.search(‘super’,’insuperable’).span())
(2,7)
- 反斜杠灾难
在python中,字符串中使用反斜杠有可能带来反斜杠灾难。假设你想要编写一个与字符串 \section 相匹配的正则,它可以在 LaTeX 文件中找到。 要找出在程序代码中写入的内容,请从要匹配的字符串开始。 接下来,您必须通过在反斜杠前面添加反斜杠和其他元字符,从而产生字符串 \\section。 必须传递给 re.compile() 的结果字符串必须是 \\section。 但是,要将其表示为 Python 字符串文字,必须 再次转义两个反斜杠。
简而言之,要匹配文字反斜杠,必须将 '\\\\' 写为正则字符串,因为正则表达式必须是 \\,并且每个反斜杠必须表示为 \\ 在常规Python字符串字面中。 在反复使用反斜杠的正则中,这会导致大量重复的反斜杠,并使得生成的字符串难以理解。
解决方法:解决方案是使用 Python 的原始字符串表示法来表示正则表达式;反斜杠不以任何特殊的方式处理前缀为 'r' 的字符串字面,因此 r"\n" 是一个包含 '\' 和 'n' 的双字符字符串,而 "\n" 是一个包含换行符的单字符字符串。 正则表达式通常使用这种原始字符串表示法用 Python 代码编写。
- 贪婪与非贪婪
在使用重复元字符时,存在贪婪与非贪婪特性的两类元字符,a*本意是匹配前一个字符0次到多次,不过python编译器会尽可能地进行多次匹配,因此呈现出的结果就是a的次数再允许的范围内尽可能的多。若要解决可以使用*?,+?,??或者{m,n},匹配尽可能少的文字
如:
>>> s = ‘<html><head><title>Title</title?’
>>> len(s)
32
>>> print(re.match(‘<.*>’,s).span())
(0,32)
>>> print(re.match(‘<.*>’s).group())
<html><head><title>Title</title>
>>> print (re.match(‘<.*?>,s).group())
<html>