Python中的正则表达式

发布于 2022-07-30  263 次阅读


Python中的正则表达式

1. 正则表达式语法

在python中使用正则表达式必须首先引入re包import re.

import re

现在,我们首先创建一个字符串作为搜索目标

text_to_search = '''
abcdefghijklmnopqurtuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
1234567890

Ha HaHa

MetaCharacters (Need to be escaped):
. ^ $ * + ? { } [ ] \ | ( )

coreyms.com

321-555-4321
123.555.1234
123*555*1234

Mr. Schafer
Mr Smith
Ms Davis
Mrs. Robinson
Mr. T
'''

要搜索的目标字符串可以存入pattern,然后进行搜索。

pattern = re.compile(r'abc')  #r" " for raw string. 
matches = pattern.finditer(text_to_search) 

matches是finditer()返回的一个包含所有非重叠匹配对象的迭代器。输出搜索结果可以用以下语句:

for match in matches:
  print(match)  # 
  print(match.span())  # (1, 4)

其中span=(1,4)表示在目标文本中搜索对象的索引位置。在正则表达式中,可以使用以下字符来代表不同的搜索对象:

.       - Any Character Except New Line (\n)
\d      - Digit (0-9)
\D      - Not a Digit (0-9)    ie: pattern = re.compile(r'\D')
\w      - Word Character (a-z, A-Z, 0-9, _)
\W      - Not a Word Character   ie: ie: pattern = re.compile(r'\W')
\s      - Whitespace (space, tab, newline)
\S      - Not Whitespace (space, tab, newline)

以上每个特殊字符仅能匹配一个搜索字符,为了匹配多个,可以重复使用以上字符的组合,l例如,对于text_to_search中的三个电话号码,我们可以使用pattern=re.compile(r'\d\d\d.\d\d\d.\d\d\d\d')去匹配,如果只想匹配指定的分隔符,则可以将pattern设置为pattern=re.compile(r'\d\d\d[-.]\d\d\d[-.]\d\d\d\d'),意为仅匹配使用-或者.分割的电话号码。

也可以同时使用以下表示匹配数量的特殊字符(pattern=re.compile(r'\d+.\d+.\d+'))或者直接指定出现的数量(pattern=re.compile(r'\d{3}.\d{3}.\d{4}')pattern=re.compile(r'\d{3,4}.\d{3,4}.\d{3,4}')):

Quantifiers:
*       - 0 or More
+       - 1 or More
?       - 0 or One
{3}     - Exact Number
{3,4}   - Range of Numbers (Minimum, Maximum)

当需要匹配多个字符的组合时,可以借用以下特殊符号:

[]      - Matches Characters in brackets; ie: pattern = re.compile(r'[abc]')
          匹配任意包含在[]中的一个字符
[^ ]    - Matches Characters NOT in brackets
          IE: pattern = re.compile(r'[^b]at')  #匹配*at三个字母,*不为b
|       - Either Or
( )     - Group

例如,为了匹配text_to_search中的Mr开头的名字,我们可以将匹配模式设定为:pattern = re.compile(r'Mr.?\s[A-Z]'),其中?表示可以有或者没有.。为了匹配更多选定的称呼前缀,还可以按如下方式定义pattern:

pattern = re.compile(r'(Mr|Mrs|Ms)\.?\s[A-Z]\w*')

其他的匹配方式还有:

b      - Word Boundary
\B      - Not a Word Boundary
^       - Beginning of a String
          IE: pattern = re.compile(r'^start', re.I)  # re.I 忽略大小写
- End of a String
          IE: pattern = re.compile(r'end', re.I)  # re.I 忽略大小写

2. 不同的搜索方式对比

re.search() vs. re.match()

Python 提供了两种基于正则表达式的不同原始操作:re.match() 只检查字符串开头的匹配,而 re.search() 则检查字符串中任何地方的匹配。

pattern = re.compile(r'c')
text_to_search = 'abcdef'
re.match(pattern, text_to_search)    # No match, no return
re.search(pattern, text_to_search)   # Match, ruturn match result
>>> 

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

返回一个迭代器,包含与与re模式(pattern)的所有非重叠的匹配对象。从左到右扫描字符串,并按照找到的顺序返回匹配对象。

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

如果正好有一个组,返回一个与该组相匹配的字符串的列表。如果有多个组,则返回一个与组相匹配的元组列表。与finditer相比返回值仅为匹配值的列表,不包括位置等信息。

>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]

3. 例子

3.1 电子邮件地址的匹配

如果我们有如下的电子邮件地址需要匹配:

emails = '''
CoreyMSchafer@gmail.com
corey.schafer@university.edu
corey-321-schafer@my-work.net
'''

则可以将匹配模式定义为:

pattern = re.compile(r'[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+')
matches = pattern.finditer(emails)
for match in matches:
    print(match)

3.2 网址匹配

如果我们有如下网址需要匹配:

urls = '''
https://www.google.com
http://coreyms.com
https://youtube.com
https://www.nasa.gov
'''

我们可以将匹配模式定义为:

pattern = re.compile(r'https?://(www\.)?(\w+)(\.\w+)')

subbed_urls = pattern.sub(r'\2\3', urls) # only match group(2) and (3).

print(subbed_urls)

# matches = pattern.finditer(urls)

# for match in matches:
#     group(0) is the who pattern
#     print(match.group(3)) # 将匹配模式分组()后可以分组匹配

4. 总结

在Python中使用正则表达式需要以下步骤:

  • 引入re模块 import re
  • 创建搜索模式pattern
  • 利用re.search或者re.finditer()
  • 输出搜索结果

-- 本文为[Python Tutorial: re Module - How to Write and Match Regular Expressions (Regex)](Python Tutorial: re Module - How to Write and Match Regular Expressions (Regex) - YouTube笔记

Python-Regular-Expressions

届ける言葉を今は育ててる
最后更新于 2022-07-30