正则表达式

正则表达式

Yiuhang Chan

re模块

正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在Python中,正则表达式的功能通过 re 模块提供。这个模块包含了各种基于正则表达式的操作,比如匹配、查找、替换等。

re.match()

re.match() 方法用于从字符串的开始位置匹配一个模式。如果匹配成功,返回一个匹配对象;如果不匹配,返回 None

1
2
3
4
5
6
7
8
9
10
import re

pattern = r"Hello"
string = "Hello World"
match = re.match(pattern, string)

if match:
print("Match found:", match.group())
else:
print("No match")

这个例子中,pattern 是我们要查找的模式(”Hello”),而 string 是我们要搜索的字符串(”Hello World”)。由于 “Hello World” 以 “Hello” 开头,所以 re.match() 会找到一个匹配。

re.search() 方法在整个字符串中搜索模式的第一个匹配项。如果找到匹配项,返回一个匹配对象;如果没有找到,返回 None

1
2
3
4
5
6
7
8
9
10
import re

pattern = r"World"
string = "Hello World"
search = re.search(pattern, string)

if search:
print("Match found:", search.group())
else:
print("No match")

在这个例子中,尽管 “World” 不是字符串 “Hello World” 的开始部分,re.search() 依然可以找到匹配项。

re.findall()

re.findall() 方法在字符串中找到正则表达式所匹配的所有子串,并返回一个列表。如果没有找到匹配的,则返回一个空列表。

1
2
3
4
5
6
7
import re

pattern = r"l"
string = "Hello World"
findall = re.findall(pattern, string)

print("Matches found:", findall)

这里,re.findall() 查找 “Hello World” 中所有的 “l” 字符。因此,它会返回 ['l', 'l']

注意事项

  • 正则表达式是一个复杂的主题,有很多特殊字符和模式,如特殊字符 *, +, ?, {},以及字符类 [] 等。
  • 在使用 re 模块时,通常建议使用原始字符串(如 r"Hello"),这样可以避免Python对字符串中的反斜杠进行转义。
  • 返回的匹配对象有多个方法,如 group(),可以用来获取匹配的特定部分。

元字符

元字符 描述 示例 示例说明
. 匹配任何单个字符(除换行符) ".a" 匹配 ‘ca’ 在 “cat” 中
^ 匹配字符串的开始 "^Hello" 匹配 ‘Hello’ 在 “Hello World” 的开始
$ 匹配字符串的结束 "World$" 匹配 ‘World’ 在 “Hello World” 的结束
* 匹配0次或多次前面的字符 "ho*" 匹配 ‘hooo’ 在 “hoooray” 中
+ 匹配1次或多次前面的字符 "ho+" 匹配 ‘hooo’ 在 “hoooray” 中
? 匹配0次或1次前面的字符 "ho?" 匹配 ‘ho’ 在 “hoooray” 中
{m,n} 匹配至少 m 次,最多 n 次前面的字符 "(ho){1,2}" 匹配 ‘hoho’ 在 “hohohooray” 中
[] 匹配方括号中的任意一个字符 "[Hh]ello" 匹配 ‘hello’ 在 “hello” 中
[^] 匹配不在方括号中的任意一个字符 "[^abc]" 匹配 ‘g’ 在 “g” 中
` ` “或” 操作,匹配符号左或右的字符 `”cat
() 创建捕获组 `”(hello hi) (world
\d 匹配任何十进制数字 "\d+" 匹配 ‘1234’ 在 “Room number: 1234” 中
\D 匹配任何非数字字符 "\D+" 匹配 ‘ABC’ 在 “1234ABC” 中
\s 匹配任何空白字符 "\s" 匹配空格在 “Hello World” 中
\S 匹配任何非空白字符 "\S+" 匹配 ‘Hello’ 在 “ Hello World” 中
\w 匹配任何字母数字字符 "\w+" 匹配 ‘_hello123’ 在 “_hello123” 中
\W 匹配任何非字母数字字符 "\W+" 匹配 ‘,’ 在 “Hello, World!” 中
\b 匹配一个单词边界 "\bWorld\b" 匹配 ‘World’ 在 “Hello World!” 中
\B 匹配非单词边界 "\BWorld\B" 在 “HelloWorld!” 中不匹配

点号 (.)

表示任何单个字符(除了换行符)。

示例:

1
2
3
4
5
import re
pattern = r".a"
string = "cat"
match = re.search(pattern, string)
print(match.group()) # 输出: ca

脱字符 (^)

匹配字符串的开头。

示例:

1
2
3
4
5
import re
pattern = r"^Hello"
string = "Hello World"
match = re.search(pattern, string)
print(match.group()) # 输出: Hello

美元符号 ($)

匹配字符串的结尾。

示例:

1
2
3
4
5
import re
pattern = r"World$"
string = "Hello World"
match = re.search(pattern, string)
print(match.group()) # 输出: World

星号 (*)

表示0次或多次匹配前面的字符。

示例:

1
2
3
4
5
import re
pattern = r"ho*"
string = "hoooray"
match = re.search(pattern, string)
print(match.group()) # 输出: hooo

加号 (+)

表示1次或多次匹配前面的字符。

示例:

1
2
3
4
5
import re
pattern = r"ho+"
string = "hoooray"
match = re.search(pattern, string)
print(match.group()) # 输出: hooo

问号 (?)

表示0次或1次匹配前面的字符。

示例:

1
2
3
4
5
import re
pattern = r"ho?"
string = "hoooray"
match = re.search(pattern, string)
print(match.group()) # 输出: ho

花括号 ({m,n})

表示至少 m 次,最多 n 次匹配前面的字符。

示例:

1
2
3
4
5
import re
pattern = r"(ho){1,2}"
string = "hohohooray"
match = re.search(pattern, string)
print(match.group()) # 输出: hoho

方括号 ([])

用于表示一组字符中的任何一个字符。

示例:

1
2
3
4
5
import re
pattern = r"[Hh]ello"
string = "hello"
match = re.search(pattern, string)
print(match.group()) # 输出: hello

反斜杠 ()

用于转义特殊字符或表示特殊序列。

示例:

1
2
3
4
5
import re
pattern = r"\d" # \d 表示任何数字
string = "number 5"
match = re.search(pattern, string)
print(match.group()) # 输出: 5

竖杠 (|)

表示“或”操作。

示例:

1
2
3
4
5
import re
pattern = r"cat|dog"
string = "I like cats"
match = re.search(pattern, string)
print(match.group()) # 输出: cat

小括号 (())

用于创建捕获组。

示例:

1
2
3
4
5
6
import re
pattern = r"(hello|hi) (world|earth)"
string = "hello world"
match = re.search(pattern, string)
print(match.group()) # 输出: hello world
print(match.group(1)) # 输出: hello

数字和字母的特殊序列

  • \d: 匹配任何十进制数字,等同于 [0-9]

    1
    2
    3
    pattern = r"\d+"
    string = "Room number: 1234"
    print(re.search(pattern, string).group()) # 输出: 1234
  • \D: 匹配任何非数字字符,等同于 [^0-9]

    1
    2
    3
    pattern = r"\D+"
    string = "1234ABC"
    print(re.search(pattern, string).group()) # 输出: ABC
  • \s: 匹配任何空白字符。

    1
    2
    3
    pattern = r"\s"
    string = "Hello World"
    print(re.search(pattern, string).group()) # 输出: (空格字符)
  • \S: 匹配任何非空白字符。

    1
    2
    3
    pattern = r"\S+"
    string = " Hello World"
    print(re.search(pattern, string).group()) # 输出: Hello
  • \w: 匹配任何字母数字字符,等同于 [a-zA-Z0-9_]

    1
    2
    3
    pattern = r"\w+"
    string = "_hello123"
    print(re.search(pattern, string).group()) # 输出: _hello123
  • \W: 匹配任何非字母数字字符,等同于 [^a-zA-Z0-9_]

    1
    2
    3
    pattern = r"\W+"
    string = "Hello, World!"
    print(re.search(pattern, string).group()) # 输出: ,

边界匹配符

  • \A 和 \Z

    \A\Z 分别用于匹配字符串的开头和结尾。它们类似于 ^$,但主要区别在于,\A\Z 不受多行模式的影响,而 ^$ 在多行模式(re.MULTILINE)下分别匹配每一行的开头和结尾。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import re

    # \A 匹配字符串开头
    pattern = r"\AHello"
    string = "Hello World"
    match = re.search(pattern, string)
    print(match.group()) # 输出: Hello

    # \Z 匹配字符串结尾
    pattern = r"World\Z"
    string = "Hello World"
    match = re.search(pattern, string)
    print(match.group()) # 输出: World
  • \b: 匹配一个单词边界,即单词和空格之间的位置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import re

    # 匹配单词边界
    pattern = r"\bWorld\b"
    string = "Hello World!"
    match = re.search(pattern, string)
    print(match.group()) # 输出: World

    # 不匹配非边界位置
    pattern = r"\bWorld\b"
    string = "HelloWorld!"
    match = re.search(pattern, string)
    print(match) # 输出: None
  • \B: 匹配非单词边界。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    import re

    # 匹配非单词边界
    pattern = r"\BWorld\B"
    string = "HelloWorld!"
    match = re.search(pattern, string)
    print(match.group()) # 输出: World

    # 不匹配单词边界位置
    pattern = r"\BWorld\B"
    string = "Hello World!"
    match = re.search(pattern, string)
    print(match) # 输出: None

原始字符串

r 前缀在Python中用于表示原始字符串(raw string)。在正则表达式中,这个前缀非常重要,因为它确保了字符串中的特殊字符(如反斜杠 \)不会被Python解释器作为转义字符处理。在编写正则表达式时,建议总是使用原始字符串。

为什么使用原始字符串?

在正则表达式中,反斜杠 \ 用于指示特殊序列或作为转义字符。如果不使用原始字符串,Python解释器会首先解释这个反斜杠。例如,\n 在普通的Python字符串中表示换行符,但在正则表达式中可能表示一个特殊序列。使用原始字符串可以避免这种混淆。

示例

不使用原始字符串:

1
2
3
4
5
6
import re

pattern = "\\bword\\b"
string = "A word and another word."
match = re.search(pattern, string)
print(match.group()) # 这将不会工作如预期

在这个例子中,每个 \ 都必须写成 \\,因为Python字符串会尝试解释 \b 作为一个退格符。

使用原始字符串:

1
2
3
4
5
6
import re

pattern = r"\bword\b"
string = "A word and another word."
match = re.search(pattern, string)
print(match.group()) # 输出: word

在这个例子中,使用 r 前缀,所以 \b 被正确地解释为单词边界匹配符,而不是退格符。

当编写涉及到反斜杠的正则表达式时,总是使用原始字符串(如 r"\bword\b")来确保反斜杠被正确处理。这样可以让正则表达式更易读,也减少了由于转义字符引起的错误。

案例

QQ邮箱

1
2
3
4
5
import re

mail = "daf ghsegtw345 [email protected] ewsafc3"

print(re.findall(r'\d{5,10}@qq\.com', mail))

手机号

1
2
3
4
5
import re

phone = "13312345678"

print(re.findall(r'^1[3-9]\d{9}$', phone))
  • 标题: 正则表达式
  • 作者: Yiuhang Chan
  • 创建于 : 2018-10-12 18:24:40
  • 更新于 : 2024-02-28 18:49:20
  • 链接: https://www.yiuhangblog.com/2018/10/12/20181012正则表达式/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论