python初步学习-Python模块之 re

python

re 正则表达式

python正则表达式在线检验网站

python re正则表达式语法

  • 匹配字符

语法解释表达式匹配实例
.匹配任意除“\n”以外的任何字符a.cabc
\转义符,改变原来符号含义
如果字符串中有字符 * 需要匹配,可以使用 \* 或者字符集[*]
a.c
a\c
abe
ace
ade
[]字符集。对应的位置可以是字符集中任意字符。
字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。第一个字符如果是则表示取反,如[abc]表示不是abc的其他字符
a[bcd]eabc
ace
ade

  • 预定义字符集(可以写在字符集[...]中)

语法解释表达式匹配实例
\d数字:[0-9]a\dca1c
a9c
\D非数字: [^\d]
[^0-9]
a\Dcabc
azc
\s空白字符:[<空格>\t\r\n\f\v]a\sca c
a\tc
a\nc
\S非空白字符:[^\s]a\Scabc
a1c
\w单词字符:[A-Za-z0-9]a\wcabc
\W非单词字符:[^\w]a\Wca c

  • 数量词(用在字符或(...)之后)

语法解释表达式匹配实例
*匹配前一个字符0或无限次abc*ab
abccc
+匹配前一个字符1次或无限次abc+abc
abccc
?匹配前一个字符0次或1次abc?ab
abc
{m}匹配前一个字符m次ab{2}cabbc
{m,n}匹配前一个字符m至n次
m和n可以省略:若省略m,则匹配0至n次
若省略n,则匹配m至无限次
ab{1,2}cabc
abbc

?
+?
??*
{m,n}?

使 * + ? {m,n}变成非贪婪模式

  • 边界匹配(不消耗待匹配字符串中的字符)

语法解释表达式
^匹配字符串开头
在多行模式中匹配每一行的开头
^abc
$匹配字符串末尾
在多行模式中匹配每一行的末尾
abc$
\A仅匹配字符串开头\Aabc
\Z仅匹配字符串末尾abc\Z
\b匹配\w和\W之间a\b!bc
\B[^\b]a\Bbc

  • 逻辑、分组

语法解释表达式匹配实例
||代表左右表达式任意匹配一个
它总是先尝试匹配左边的表达式,一旦成功匹配则跳过匹配走遍的表达式
如果|表达式没有被包含在()中,则它的范围是整个正则表达式
abc|defabc
def
(...)被阔气来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号"(",编号+1.
另外,分组表达式作为一个整体,可以后接数量词。
表达式中的|仅在该组中有效。
(abc){2}
a(123
456)
(?P...)分组,除了原有的编号外在指定一个额外的字符串(?Pabc){2}

abcabc
<number>引用编号为的分组匹配到的字符串

(\d)abc\11abc1
5abc5
(?P=name)引用别名为的分组匹配到的字符串

(?P\d)abc(?p=id)

1abc1
5abc5

+++ 数量词的贪婪模式和非贪婪模式

正则表达式通常用于文本中查找匹配的字符串。Python 里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找“abbbc”,将找到“abbb”。而如果使用非贪婪的数量词"ab*?",将找到"a".

re 模块

  • re.complie([pattern[,flags]])

把一个正则表达式 pattern 编译成正则对象,以便可以用正则对象的 match和search 方法。第二个参数flag是匹配模式,取值可以使用按位或运算符'|'表示同时生效,比如re.I | re.M。另外,你也可以在regex字符串中指定模式,比如re.compile('pattern', re.I | re.M)与re.compile('(?im)pattern')是等价的。

可选值有:

  • re.I(re.IGNORECASE): 忽略大小写(括号内是完整写法,下同)
  • M(MULTILINE): 多行模式,改变'^'和'$'的行为(参见上图)
  • S(DOTALL): 点任意匹配模式,改变'.'的行为
  • L(LOCALE): 使预定字符类 \w \W \b \B \s \S 取决于当前区域设定
  • U(UNICODE): 使预定字符类 \w \W \b \B \s \S \d \D 取决于unicode定义的字符属性
  • X(VERBOSE): 详细模式。这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。以下两个正则表达式是等价的:

a = re.compile(r"""\d +  # the integral part

\. # the decimal point

\d * # some fractional digits""", re.X)

b = re.compile(r"\d+\.\d*")

表达式前面之所以有一个 r ,是表示 后面为原字符,如一些特殊符号需要转义比较麻烦,前面加一个 r,就可以一劳永逸了。

一下两段内容在语法上是等效的:

prog = re.compile(pattern)

result = prog.match(string)

result = re.match(pattern, string)

区别是,用了 re.compile 以后,正则对象会得到保留,这样在需要多次运用这个正则对象的时候,效率会有较大的提升。如下面的例子:

In [1]: import timeit

In [2]: timeit.timeit(

...: ... setup='''import re; reg = re.compile('<(?P<tagnam

...: e>\w*)>.*</(?P=tagname)>')''',

...: ... stmt='''reg.match('<h1>xxx</h1>')''',

...: ... number=1000000)

Out[2]: 0.5159049034118652

In [3]: timeit.timeit(

...: ... setup='''import re''',

...: ... stmt='''re.match('<(?P<tagname>\w*)>.*</(?P=tagna

...: me)>', '<h1>xxx</h1>')''',

...: ... number=1000000)

Out[3]: 1.5837020874023438

可以看到速度提升了3倍。

  • match()

格式:re.match(pattern,string,flags=0)

如果匹配成功将返回一个 match() 对象,否则返回 None;

match()对象是一次匹配的结果,包含了很多关于此次匹配的信息,可以使用 match() 提供的可读属性或方法来获取这些信息。

In [30]: s1 = "hello world"

In [31]: p = re.compile(r"(he)")

In [32]: result = re.match(p,s1)

In [33]: print result

<_sre.SRE_Match object at 0x7f6a8c48bf30>

In [35]: print result.string

hello world

In [37]: print result.group()

he

  • search()

格式:re.search(pattern,string,flags=0)

re.search()函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回 None

print(re.search('\dcom','www.4comrunoob.5com').group())

执行结果如下:

4com

注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:

  • group() 返回被 RE 匹配的字符串
  • start() 返回匹配开始的位置
  • end() 返回匹配结束的位置
  • span() 返回一个元组包含匹配 (开始,结束) 的位置
  • group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。

    • a.group() 返回 re 整体匹配的字符串
    • b.group(n,m)返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常
    • c.groups() groups()方法返回一个包含正则表达式中所有小组字符串的元组,从1到所含的小组号,通常groups()不需要参数,返回一个元组,元组中的元就是正则表达式中定义的组

import re

a = "123abc456"

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)) #123abc456,返回整体

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)) #123

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)) #abc

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)) #456

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1,2)) #('123', 'abc')

print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).groups()) #('123', 'abc', '456')

需要注意一点的是,search()的效率要比match()的效率低。因为 search() 会对整个字符串进行扫描,而 match() 只会从头开始匹配,如果开头匹配失败,则 return None。所以 search() 匹配需要花费的时间很多。推荐使用 match().

findall()

re.findall()遍历匹配,可以获得字符串中所有匹配的字符串,返回一个列表。

格式:

re.findall(pattern,string,flags=0)

p = re.compile(r"\d+")

print p.findall("one1two2three3four4")

执行结果如下:

['1', '2', '3', '4']

import re

tt = "Tina is a good girl, she is cool, clever, and so on..."

rr = re.compile(r'\w*oo\w*')

print re.findall(rr,tt)

['good', 'cool']

print re.findall(r'(\w)*oo(\w)',tt)

[('g', 'd'), ('c', 'l')]

finditer()

搜索string,返回一个顺序访问每一个匹配结果(match对象)的迭代器,找到 re 匹配的所有字符串,并把它们作为一个迭代器返回

格式:

re.finditer(pattern, string, flags=0)

iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...')

for i in iter:

print(i)

print(i.group())

print(i.span())

执行结果如下:

<_sre.SRE_Match object; span=(0, 2), match='12'>

12

(0, 2)

<_sre.SRE_Match object; span=(8, 10), match='44'>

44

(8, 10)

<_sre.SRE_Match object; span=(24, 26), match='11'>

11

(24, 26)

<_sre.SRE_Match object; span=(31, 33), match='10'>

10

(31, 33)

split()

能够按照匹配的字符串将 string 分割后返回列表

格式:

re.split(pattern,string[,maxsplit])

maxsplit 用于指定最大分割次数,不指定将全部分割

print re.spilt(r'\d+','one1two2three3four4five5')

执行结果如下:

['one', 'two', 'three', 'four', 'five', '']

以上是 python初步学习-Python模块之 re 的全部内容, 来源链接: utcz.com/z/388993.html

回到顶部