一、概述

**正则表达式(Regular Expression)**是一种文本形式,用于匹配字符串中的形式。它能够用于许多使命,例如文本查找和替换,数据提取,数据验证等。

  • 在 Python 中,能够运用 re 模块来支撑正则表达式。正则表达式运用特别的字符来表明不同的形式,例如 . 匹配恣意字符,\d 匹配数字,^ 匹配字符串最初,$ 匹配字符串完毕等。

  • 经过运用正则表达式,能够很方便地对字符串进行匹配,查找和替换等操作。运用正则表达式的时候,需要先编写一个匹配形式,然后运用 re 模块中的函数来执行实际的匹配操作。

总的来说,正则表达式是一种强大且高效的文本处理东西,能够用于解决许多实际问题。

Python 高级编程之正则表达式(八)

二、正则表达式语法

正则表达式(Regular Expression,简称 regex 或 regexp)是一种用来匹配文本形式的东西,它能够用来查找、替换和验证文本。正则表达式由一些特别字符和一般字符组成,这些字符表明了一些形式。

下面是一些常见的正则表达式语法:

1)字符匹配

  • 一般字符:表明自身,例如 “a” 表明字符 a。
  • 元字符(特别字符):表明某种特别意义,例如 “.” 表明匹配恣意字符,”\d” 表明匹配数字,”\w” 表明匹配字母、数字、下划线。

示例:

import re
# 匹配 "abc" 字符串
pattern = "abc"
text = "abc"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 3), match='abc'>
# 匹配恣意字符
pattern = "."
text = "abc"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>
# 匹配数字
pattern = "\d"
text = "123"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='1'>
# 匹配字母、数字、下划线
pattern = "\w"
text = "abc_123"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>

2)字符集合

  • 括号:表明匹配方括号中恣意一个字符,例如 “[abc]” 表明匹配字符 a、b、c 中的恣意一个。
  • 规模符号:表明匹配某个规模内的字符,例如 “[a-z]” 表明匹配小写字母 a 到 z 中的恣意一个。
  • 量词:””, “+”, “?”: 表明重复次数,”” 表明重复0次或屡次,”+” 表明重复1次或屡次,”?” 表明重复0次或1次。
  • "{m,n}": 表明重复次数的规模,例如 “{2,4}” 表明重复2到4次。

示例:

import re
# 匹配方括号中恣意一个字符
pattern = "[abc]"
text = "a"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>
# 匹配小写字母 a 到 z 中的恣意一个
pattern = "[a-z]"
text = "a"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>
# 重复0次或屡次
pattern = "a*"
text = "aaa"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 3), match='aaa'>
# 重复1次或屡次
pattern = "a+"
text = "aaa"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 3), match='aaa'>
# 重复0次或1次
pattern = "a?"
text = "aaa"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>
# 重复2到4次
pattern = "a{2,4}"
text = "aaaa"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 4), match='aaaa'>

3)定位

  • "^": 表明匹配最初。
  • "$": 表明匹配完毕。
  • "\b": 表明匹配单词鸿沟。
import re
# 匹配最初
pattern = "^a"
text = "abc"
result = re.match(pattern, text)
print(result) # <re.Match object; span=(0, 1), match='a'>
# 匹配完毕
pattern = "c$"
text = "abc"
result = re.search(pattern, text)
print(result) # <re.Match object; span=(2, 3), match='c'>
# 匹配单词鸿沟
pattern = r"\bcat\b"
text = "cat sat on the mat"
result = re.search(pattern, text)
print(result) # <re.Match object; span=(0, 3), match='cat'>

4)分组

  • "()", "(?:)": 表明分组,能够对一个子表达式进行分组。
  • "|": 表明或关系。

1、界说分组

运用圆括号 () 来界说分组,分组能够嵌套,每个分组都有一个唯一的编号,从左到右依照左括号的次序编号。

import re
pattern = r"(\d{3})-(\d{4})-(\d{4})"
result = re.search(pattern, "Tel: 010-1234-5678")
print(result.group(0))  # 010-1234-5678
print(result.group(1))  # 010
print(result.group(2))  # 1234
print(result.group(3))  # 5678

2、引证分组

能够在正则表达式中运用 \n 引证第 n 个分组,其间 n 是分组的编号。

import re
pattern = r"(\w+) \1"
result = re.search(pattern, "hello hello world")
print(result.group(0))  # hello hello
print(result.group(1))  # hello

3、命名分组

除了运用编号引证分组,还能够运用 (?Ppattern) 语法给分组命名。

import re
pattern = r"(?P<first>\w+) (?P<last>\w+)"
result = re.search(pattern, "John Smith")
print(result.group(0))  # John Smith
print(result.group("first"))  # John
print(result.group("last"))  # Smith

以上仅是正则表达式语法的一部分,实际上正则表达式还包括许多高级的语法,比如反向引证、零宽度断语等。上面讲运用到了Python 的re形式,接下来细讲这个模块。

三、Python 的 re 模块

Python规范库中的re模块是用于正则表达式操作的模块,供给了正则表达式的编译、匹配、查找、替换等功能。下面是re模块的一些常用办法:

1)re.match() 办法

re.match() 函数从字符串的开始方位开端匹配正则表达式,假如匹配成功,就回来一个匹配目标。假如匹配不成功,就回来 None。

re.match() 的语法格局如下:

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

参数:

  • pattern 是正则表达式
  • string 是要匹配的字符串
  • flags 是可选参数,用于指定匹配形式。

正则表达式能够包括一些可选标志修饰符来控制匹配的形式。修饰符被指定为一个可选的标志。多个标志能够经过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描绘
re.I 使匹配对大小写不敏感
re.M 多行匹配,影响 ^ 和 $
re.L 做本地化辨认(locale-aware)匹配
re.S 使 . 匹配包括换行在内的一切字符
re.U 依据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B
re.X 该标志经过给予你更灵敏的格局以便你将正则表达式写得更易于了解。

下面是一个简略的比如:

import re
pattern = r"hello"
string = "hello world"
match_obj = re.match(pattern, string)
if match_obj:
    print("匹配成功")
else:
    print("匹配失利")

在这个比如中,正则表达式 pattern 是 “hello”,要匹配的字符串是 “hello world”。因为正则表达式和字符串的最初都是 “hello”,所以匹配成功。

re.match() 回来的是一个匹配目标。假如匹配成功,能够运用匹配目标的办法和特点来获取匹配成果,如 group() 办法能够回来匹配的字符串,start() 和 end() 办法能够回来匹配的开始方位和完毕方位,等等。假如匹配不成功,调用这些办法和特点会出现异常。

  • start() 回来匹配开端的方位
  • end() 回来匹配完毕的方位
  • span() 回来一个元组包括匹配 (开端,完毕) 的方位

下面是一个获取匹配成果的比如:

import re
pattern = r"hello"
string = "hello world"
match_obj = re.match(pattern, string)
if match_obj:
    print("匹配成功")
    print(match_obj.group())     # hello
    print(match_obj.start())     # 0
    print(match_obj.end())       # 5
    print(match_obj.span())      # (0, 5)
else:
    print("匹配失利")

2)re.search() 办法

re.search() 办法在字符串中查找正则表达式的第一个匹配项,并回来一个匹配目标。假如没有找到匹配项,就回来 None。

re.search() 的语法格局如下:

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

其间,pattern 是正则表达式,string 是要匹配的字符串,flags 是可选参数,用于指定匹配形式。匹配形式在上面有详细解说。

下面是一个简略的比如:

import re
pattern = r"hello"
string = "world hello"
match_obj = re.search(pattern, string)
if match_obj:
    print("匹配成功")
else:
    print("匹配失利")

在这个比如中,正则表达式 pattern 是 “hello”,要匹配的字符串是 “world hello”。因为字符串中包括 “hello”,所以匹配成功。

3)re.match() 与 re.search() 的差异

Python re 模块中的 re.match()re.search() 办法都用于在字符串中查找匹配的形式。但是它们之间有一些差异。

  • re.match() 办法从字符串的开始方位开端匹配,假如开始方位不匹配,则回来 None。因而,re.match() 只能匹配到字符串的最初。
  • re.search() 办法在字符串中查找匹配的形式,能够匹配到字符串中恣意方位的形式。

别的,两个办法回来的匹配目标也有一些差异:

  • re.match() 办法回来第一个匹配的目标,假如没有匹配到任何内容,则回来 None。
  • re.search() 办法回来第一个匹配的目标,假如没有匹配到任何内容,则回来 None。

假如要匹配整个字符串,一般主张运用 re.match() 办法;假如要匹配字符串中的一部分,或许不确定匹配的方位,一般主张运用 re.search() 办法。

下面是一个比如,展示了两个办法之间的差异:

import re
pattern = r"hello"
string = "world hello"
# 运用 re.match() 办法
match_obj = re.match(pattern, string)
if match_obj:
    print("re.match() 匹配成功")
    print(match_obj.group())   # 输出 "None"
# 运用 re.search() 办法
match_obj = re.search(pattern, string)
if match_obj:
    print("re.search() 匹配成功")
    print(match_obj.group())   # 输出 "hello"

在这个比如中,正则表达式 pattern 是 “hello”,要匹配的字符串是 “world hello”。因为字符串的最初不是 “hello”,所以 re.match() 办法无法匹配,回来 None;而 re.search() 办法能够在字符串中找到 “hello”,匹配成功。

4)re.findall() 办法

re.findall() 办法用于在字符串中查找正则表达式匹配的一切子串,并回来一个列表。假如没有匹配项,回来一个空列表。

re.findall() 办法的语法格局如下:

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

其间,pattern 是正则表达式,string 是要匹配的字符串,flags 是可选参数,用于指定匹配形式。匹配形式在上面有详细解说。

下面是一个简略的比如:

import re
pattern = r"\d+"
string = "2 apples, 5 bananas, 1 orange"
result = re.findall(pattern, string)
print(result)   # ['2', '5', '1']

在这个比如中,正则表达式 pattern 是 “\d+”,要匹配的字符串是 “2 apples, 5 bananas, 1 orange”。”\d+” 表明匹配一个或多个数字,所以回来的成果是一个包括一切数字的列表。

【留意】re.findall() 办法回来的是一个字符串列表,其间的每个字符串都是一个匹配的子串。假如正则表达式包括分组,回来的列表将包括一切分组匹配的字符串。

5)re.finditer() 办法

re.finditer() 办法与 re.findall() 办法类似,都能够在字符串中运用正则表达式进行匹配,但它回来的不是一个列表,而是一个迭代器,能够经过迭代器逐一拜访匹配成果。

re.finditer() 办法的语法格局如下:

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

其间,pattern 是正则表达式,string 是要匹配的字符串,flags 是可选参数,用于指定匹配形式。

下面是一个简略的比如:

import re
pattern = r"\d+"
string = "2 apples, 5 bananas, 1 orange"
result = re.finditer(pattern, string)
for match in result:
    print(match.group())

在这个比如中,正则表达式 pattern 是 “\d+”,要匹配的字符串是 “2 apples, 5 bananas, 1 orange”。运用 re.finditer() 办法进行匹配,回来的成果是一个迭代器,能够经过 for 循环逐一拜访匹配成果。每个匹配成果都是一个 Match 目标,能够运用 match.group() 办法获取匹配的内容。

re.finditer() 办法与 re.findall() 办法的差异在于,re.findall() 办法回来一个包括一切匹配成果的列表,而 re.finditer() 办法回来一个迭代器,能够逐一拜访匹配成果,这在处理很多数据时能够节省内存。

6)re.sub() 办法

re.sub() 办法用于在字符串中查找正则表达式匹配的子串,并将其替换为指定的字符串。re.sub() 办法回来替换后的字符串。

re.sub() 办法的语法格局如下:

re.sub(pattern, repl, string, count=0, flags=0)

其间,pattern 是正则表达式,repl 是替换字符串,string 是要进行替换的字符串,count 是可选参数,用于指定最多替换的次数,flags 是可选参数,用于指定匹配形式。

下面是一个简略的比如:

import re
pattern = r"\s+"
string = "hello  world"
result = re.sub(pattern, "-", string)
print(result)   # 'hello-world'

在这个比如中,正则表达式 pattern 是 “\s+”,要匹配的字符串是 “hello world”,”\s+” 表明匹配一个或多个空格。repl 参数是 “-“,表明将匹配到的空格替换为 “-“,成果回来的是 “hello-world”。

【留意】re.sub() 办法并不会改变原始的字符串,而是回来一个新的字符串。假如想要在原始字符串中进行替换,能够将成果赋值给原始字符串变量

7)re.compile() 办法

re.compile() 办法用于将正则表达式编译为一个形式目标,该形式目标能够用于匹配字符串。

re.compile() 办法的语法格局如下:

re.compile(pattern, flags=0)

其间,pattern 是要编译的正则表达式,flags 是可选参数,用于指定匹配形式。

编译后的形式目标能够调用 match()、search()、findall() 和 sub() 等办法进行匹配和替换操作。运用 re.compile() 办法编译正则表达式能够进步屡次运用同一形式的效率。

下面是一个简略的比如:

import re
pattern = r"\d+"
string = "2 apples, 5 bananas, 1 orange"
regex = re.compile(pattern)
result = regex.findall(string)
print(result)   # ['2', '5', '1']

在这个比如中,正则表达式 pattern 是 “\d+”,要匹配的字符串是 “2 apples, 5 bananas, 1 orange”。运用 re.compile() 办法将正则表达式编译为一个形式目标 regex,然后调用 regex.findall() 办法进行匹配,回来的成果是一个包括一切数字的列表。

【留意】假如要运用编译后的正则表达式进行匹配,有必要调用相应的形式目标的办法。假如直接在 re 模块中运用正则表达式,Python 会自动将其编译为一个形式目标。

8)re.split() 办法

re.split() 办法用于在字符串中运用正则表达式进行切割,并回来一个列表

re.split() 办法的语法格局如下:

re.split(pattern, string, maxsplit=0, flags=0)

其间,pattern 是正则表达式,string 是要切割的字符串,maxsplit 是可选参数,用于指定最大切割次数,flags 是可选参数,用于指定匹配形式。

下面是一个简略的比如:

import re
pattern = r"\s+"
string = "hello  world"
result = re.split(pattern, string)
print(result)   # ['hello', 'world']

在这个比如中,正则表达式 pattern 是 “\s+”,要切割的字符串是 “hello world”,”\s+” 表明匹配一个或多个空格。re.split() 办法将字符串依照正则表达式进行切割,并回来一个列表,列表中的每个元素都是切割后的子串。

【留意】re.split() 办法不会在切割后的字符串中保存切割符,假如想要保存切割符,能够运用分组语法,例如:

import re
pattern = r"(\s+)"
string = "hello  world"
result = re.split(pattern, string)
print(result)   # ['hello', '  ', 'world']

在这个比如中,正则表达式 pattern 是 “(\s+)”,运用圆括号将 “\s+” 包括起来,表明将空格作为分组进行匹配,re.split() 办法会保存分组匹配的内容。回来的成果是一个列表,列表中的元素是切割后的子串和分组匹配的内容。


Python 的正则表达式常用的语法和办法就先解说到这里了,更关键还是需要多运用加深形象的。有任何疑问的小伙伴欢迎给我留言哦,后续会持续更新相关技术文章,也可关注我的大众号【大数据与云原生技术分享】进行深化技术交流~

Python 高级编程之正则表达式(八)