Python 正则表达式

原文: https://thepythonguru.com/python-regular-expression/


于 2020 年 1 月 7 日更新


正则表达式广泛用于模式匹配。 Python 具有对常规功能的内置支持。 要使用正则表达式,您需要导入re模块。

  1. import re

现在您可以使用正则表达式了。

search方法


re.search()用于查找字符串中模式的第一个匹配项。

语法re.search(pattern, string, flags[optional])

re.search()方法接受模式和字符串,并在成功时返回match对象;如果找不到匹配项,则返回Nonematch对象具有group()方法,该方法在字符串中包含匹配的文本。

您必须使用原始字符串来指定模式,即像这样用r开头的字符串。

  1. r'this \n'

所有特殊字符和转义序列在原始字符串中均失去其特殊含义,因此\n不是换行符,它只是一个反斜杠\后跟一个n

  1. >>> import re
  2. >>> s = "my number is 123"
  3. >>> match = re.search(r'\d\d\d', s)
  4. >>> match
  5. <_sre.SRE_Match object; span=(13, 16), match='123'>
  6. >>> match.group()
  7. '123'

上面我们使用\d\d\d作为模式。 \d正则表达式匹配一位数字,因此

\d\d\d将匹配111222786之类的数字。 它与121444不匹配。

正则表达式中使用的基本模式


符号 描述
. 点匹配除换行符以外的任何字符
\w 匹配任何单词字符,即字母,字母数字,数字和下划线(_
\W 匹配非单词字符
\d 匹配一个数字
\D 匹配不是数字的单个字符
\s 匹配任何空白字符,例如\n\t,空格
\S 匹配单个非空白字符
[abc] 匹配集合中的单个字符,即匹配abc
[^abc] 匹配abc以外的单个字符
[a-z] 匹配az范围内的单个字符。
[a-zA-Z] 匹配a-zA-Z范围内的单个字符
[0-9] 匹配0-9范围内的单个字符
^ 匹配从字符串开头开始
$ 匹配从字符串末尾开始
+ 匹配一个或多个前面的字符(贪婪匹配)。
* 匹配零个或多个前一个字符(贪婪匹配)。

再举一个例子:

  1. import re
  2. s = "tim email is tim@somehost.com"
  3. match = re.search(r'[\w.-]+@[\w.-]+', s)
  4. # the above regular expression will match a email address
  5. if match:
  6. print(match.group())
  7. else:
  8. print("match not found")

这里我们使用了[\w.-]+@[\w.-]+模式来匹配电子邮件地址。 成功后,re.search()返回一个match对象,其group()方法将包含匹配的文本。

捕捉组


组捕获允许从匹配的字符串中提取部分。 您可以使用括号()创建组。 假设在上面的示例中,我们想从电子邮件地址中提取用户名和主机名。 为此,我们需要在用户名和主机名周围添加(),如下所示。

  1. match = re.search(r'([\w.-]+)@([\w.-]+)', s)

请注意,括号不会更改模式匹配的内容。 如果匹配成功,则match.group(1)将包含第一个括号中的匹配,match.group(2)将包含第二个括号中的匹配。

  1. import re
  2. s = "tim email is tim@somehost.com"
  3. match = re.search('([\w.-]+)@([\w.-]+)', s)
  4. if match:
  5. print(match.group()) ## tim@somehost.com (the whole match)
  6. print(match.group(1)) ## tim (the username, group 1)
  7. print(match.group(2)) ## somehost (the host, group 2)

findall()函数


如您所知,现在re.search()仅找到模式的第一个匹配项,如果我们想找到字符串中的所有匹配项,这就是findall()发挥作用的地方。

语法findall(pattern, string, flags=0[optional])

成功时,它将所有匹配项作为字符串列表返回,否则返回空列表。

  1. import re
  2. s = "Tim's phone numbers are 12345-41521 and 78963-85214"
  3. match = re.findall(r'\d{5}', s)
  4. if match:
  5. print(match)

预期输出

  1. ['12345', '41521', '78963', '85214']

您还可以通过findall()使用组捕获,当应用组捕获时,findall()返回一个元组列表,其中元组将包含匹配的组。 一个示例将清除所有内容。

  1. import re
  2. s = "Tim's phone numbers are 12345-41521 and 78963-85214"
  3. match = re.findall(r'(\d{5})-(\d{5})', s)
  4. print(match)
  5. for i in match:
  6. print()
  7. print(i)
  8. print("First group", i[0])
  9. print("Second group", i[1])

预期输出

  1. [('12345', '41521'), ('78963', '85214')]
  2. ('12345', '41521')
  3. First group 12345
  4. Second group 41521
  5. ('78963', '85214')
  6. First group 78963
  7. Second group 85214

可选标志


re.search()re.findall()都接受可选参数称为标志。 标志用于修改模式匹配的行为。

标志 描述
re.IGNORECASE 忽略大写和小写
re.DOTALL 允许(.)匹配换行符,默认(.)匹配除换行符之外的任何字符
re.MULTILINE 这将允许^$匹配每行的开始和结束

使用re.match()


re.match()re.search()非常相似,区别在于它将在字符串的开头开始寻找匹配项。

  1. import re
  2. s = "python tuts"
  3. match = re.match(r'py', s)
  4. if match:
  5. print(match.group())

您可以通过使用re.search()^应用于模式来完成同一件事。

  1. import re
  2. s = "python tuts"
  3. match = re.search(r'^py', s)
  4. if match:
  5. print(match.group())

这样就完成了您需要了解的有关re模块的所有内容。