【Python正则表达式语法总结】

Python正则表达式

1.介绍

模式和被搜索的字符串既可以是 Unicode 字符串 (str) ,也可以是8位字节串 (bytes)。 但是,Unicode 字符串与8位字节串不能混用:也就是说,你不能用一个字节串模式去匹配 Unicode 字符串,反之亦然;类似地,当进行替换操作时,替换字符串的类型也必须与所用的模式和搜索字符串的类型一致。

正则表达式使用反斜杠('\')来表示特殊形式,或者把特殊字符转义成普通字符。 当我们需要的特殊字符不能直接表示时,就需要用反斜杠进行转义。

当正则表达式很长时,需要在前面加上‘r’,就不需要进行反斜杠转义。

正则表达式可以拼接,如果 AB 都是正则表达式, 那么 AB 也是正则表达式。 通常, 如果字符串 p 匹配 A 并且另一个字符串 q 匹配 B, 那么 pq 可以匹配 AB。除非 A 或者 B 包含低优先级操作,AB 存在边界条件;或者命名组引用。

有些字符,比如 '|' 或者 '(',属于特殊字符。 特殊字符既可以表示它的普通含义, 也可以影响它旁边的正则表达式的解释。

重复修饰符 (*, +, ?, {m,n}, 等) 不能直接嵌套。这样避免了非贪婪后缀 ? 修饰符,和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。 比如,表达式 (?:a{6})* 匹配6个 'a' 字符重复任意次数。

2.语法

2.1 .

(点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 DOTALL ,它将匹配包括换行符的任意字符。

2.2 ^

(插入符号) 匹配字符串的开头, 并且在 MULTILINE 模式也匹配换行后的首个符号。

2.3 $

匹配字符串尾或者在字符串尾的换行符的前一个字符,在 MULTILINE 模式下也会匹配换行符之前的文本。 foo 匹配 ‘foo’ 和 ‘foobar’,但正则表达式 foo$ 只匹配 ‘foo’。 更有趣的是,在 'foo1\nfoo2\n' 中搜索 foo.$,通常匹配 ‘foo2’,但在 MULTILINE 模式下可以匹配到 ‘foo1’;在 'foo\n' 中搜索 $ 会找到两个(空的)匹配:一个在换行符之前,一个在字符串的末尾。

t = 'foo1\nfoo2\n'
res = re.findall(r'foo.$', t)
print(res)

结果:[‘foo2’]

t = 'foo1\nfoo2\n'
pattern = re.compile(r'foo.$')
res = re.findall(pattern, t)
print(res)

结果:[‘foo2’]

t = 'foo1\nfoo2\n'
pattern = re.compile(r'foo.$')
res = re.findall(pattern, t, re.M)
print(res)

结果:报错:ValueError: cannot process flags argument with a compiled pattern

原因见3.1

r’foo.$’ 不等价于 re.compile(r’foo.$')

t = 'foo1\nfoo2\n'
res = re.findall(r'foo.$', t, re.M)
print(res)

结果:[‘foo1’, ‘foo2’]

t = 'foo1\nfoo2\n'

pattern = re.compile(r'foo.$')
res = pattern.findall(t, re.M)

print(res)

结果:[]

2.4 *

对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 `ab*` 会匹配 `‘a’`, `‘ab’`, 或者 `‘a’``后面跟随任意个 ``‘b’`。

t = 'abcccbab'
prog = re.compile(r'abc*')
res = prog.findall(t)
print(res)

结果:[‘abccc’, ‘ab’]

2.5 +

对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b',它不会匹配 'a'

t = 'sachaksabcbbbbsgfsgnsabaaaababbbbbbcbbbbababaaaas'

prog = re.compile(r'ab+')
res = prog.findall(t)

print(res)

结果:[‘ab’, ‘ab’, ‘ab’, ‘abbbbbb’, ‘ab’, ‘ab’]

2.6 ?

对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab'

t = 'abcccbab'
prog = re.compile(r'abc?')
res = prog.findall(t)
print(res)

结果:[‘abc’, ‘ab’]

2.7 *?,+?,??

'*', '+',和 '?' 修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式 <.*> 希望找到 ‘<a>b<c>’,它将会匹配整个字符串,而不仅是 ''。在修饰符之后添加 ? 将使样式以 非贪婪方式或者 :dfn:最小 方式进行匹配; 尽量 的字符将会被匹配。 使用正则式 <.*?> 将会仅仅匹配 '<a>'

t = '<a>b<c>'
prog = re.compile(r'<.*>')
res = prog.findall(t)
print(res)

结果:[‘<a>b<c>’]

t = '<a>b<c>'
prog = re.compile(r'<.*?>')
res = prog.findall(t)
print(res)

结果:[‘<a>’, ‘<c>’]

2.8 {m}

对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 ‘a’ , 但是不能是5个。

t = '<abbb>b<cc>'
prog = re.compile(r'b{3}')
res = prog.findall(t)
print(res)

结果:[‘bbb’]

2.9 {m,n}

对正则式进行 mn 次匹配,在 mn 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。

2.10 {m,n}?

前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于 'aaaaaa'a{3,5} 匹配 5个 'a' ,而 a{3,5}? 只匹配3个 'a'

t = '<abbbb<>bb<>bbbbbbb>b<cc>'
prog = re.compile(r'b{3,5}')
res = prog.findall(t)
print(res)

结果:[‘bbbb’, ‘bbbbb’]

t = '<abbbb<>bb<>bbbbbbb>b<cc>'
prog = re.compile(r'b{3,5}')
res = prog.findall(t)
print(res)

结果:[‘bbb’, ‘bbb’, ‘bbb’]

2.11 \

转义特殊字符(允许你匹配 '*', '?', 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。

如果你没有使用原始字符串( r'raw' )来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。

2.12 []

用于表示一个字符集合。在一个集合中:

  • 字符可以单独列出,比如 [amk] 匹配 'a''m', 或者 'k'

  • 可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 0059 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。 如果 - 进行了转义 (比如 [a\-z])或者它的位置在首位或者末尾(如 [-a][a-]),它就只表示普通字符 '-'

  • 特殊字符在集合中,失去它的特殊含义。比如 [(+*)] 只会匹配这几个文法字符 '(', '+', '*', or ')'

  • 字符类如 \w 或者 \S (如下定义) 在集合内可以接受,它们可以匹配的字符由 ASCII 或者 LOCALE 模式决定。

  • 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^' ,所有 在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 '5'[^^] 将匹配所有字符,除了 '^'. ^ 如果不在集合首位,就没有特殊含义。

  • 在集合内要匹配一个字符 ']',有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如, [()[\]{}][]()[{}] 都可以匹配括号。

  • Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个 FutureWarning 将会在有多义的情况里被 raise,包含以下几种情况,集合由 '[' 开始,或者包含下列字符序列 '--', '&&', '~~', 和 '||'。为了避免警告,需要将它们用反斜杠转义。

2.13 |

A|BAB 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 如果要匹配 '|' 字符,使用 \|, 或者把它包含在字符集里,比如 [|].

2.14 (…)

(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 '(' 或者 ')', 用 \(\), 或者把它们包含在字符集合里: [(], [)].

3.方法

3.1 re.compile(pattern, flags=0)

将正则表达式的样式编译为一个 正则表达式对象 (正则对象),可以用于匹配,通过这个对象的方法 match(), search() 以及其他如下描述。

这个表达式的行为可以通过指定 标记 的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合( | 操作符)。

序列

prog = re.compile(pattern)
result = prog.match(string)

等价于

result = re.match(pattern, string)

如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。

注解

通过 re.compile() 编译后的样式,和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值