python 之正则表达式详解

文章目录


分清字符串与字符

r与R

在Python中,前缀 rR 表示原始字符串。这种原始字符串中的反斜杠字符 \ 被视为普通字符,而不是转义字符。这在处理正则表达式、文件路径等需要保留反斜杠原始含义的情况下非常有用。

原始字符串的特点:

  1. 反斜杠不进行转义: 在普通字符串中,反斜杠具有特殊含义,如 \n 表示换行符、\t 表示制表符等。但在原始字符串中,反斜杠只是普通字符,如 \\ 会被视为两个反斜杠字符而不是转义字符。

  2. 常用于正则表达式、文件路径: 在处理正则表达式时,原始字符串非常有用,因为正则表达式经常包含大量反斜杠。同时,处理文件路径时,原始字符串能够避免不必要的转义。

示例:

正则表达式示例:
python 复制代码
import re

# 使用原始字符串处理正则表达式
pattern = r'\b\d{3}\b'  # 匹配一个三位数的单词
text = "The code is 123 and 4567."

matches = re.findall(pattern, text)
print(matches)
文件路径示例:
python 复制代码
path = r'C:\Users\Username\Documents\file.txt'
with open(path, 'r') as file:
    content = file.read()
    print(content)

这些示例演示了如何使用 rR 前缀创建原始字符串,以便在正则表达式或文件路径等场景中保留反斜杠的原始含义。

有没有r 带来的影响

在Python中,使用 r 前缀与不使用 r 前缀的主要区别是,r 前缀创建的是一个"原始字符串",其中反斜杠 \ 不会被解释为转义字符。这在处理正则表达式时特别有用,因为正则表达式本身经常包含大量反斜杠。

使用 r 前缀的示例:

python 复制代码
pattern = r'(\d{4}-\d{2}-\d{2})\s\1'

这个模式是用来匹配一个日期格式(YYYY-MM-DD),然后后面跟着相同的日期格式,两者之间有一个空格。在原始字符串中,反斜杠 \ 不会被看作是转义字符,而是作为普通字符。所以 \d 表示匹配数字字符,\s 表示匹配空白字符(空格、制表符等),\1 表示引用前面捕获的日期格式。

不使用 r 前缀的示例:

python 复制代码
pattern = '(\d{4}-\d{2}-\d{2})\s\1'

在这种情况下,没有使用 r 前缀,因此反斜杠 \ 会被看作是转义字符。这可能导致一些意想不到的结果,因为反斜杠后面的字符可能被解释为特殊字符而非字面意义。 在正则表达式中,\d 代表数字字符,\s 代表空白字符,\1 引用前面捕获的内容。

总的来说,使用 r 前缀创建原始字符串通常更适合于编写正则表达式,因为它可以让反斜杠在字符串中保持原样,避免不必要的转义。

\b 作为单词的界限

当使用 \b 作为单词边界的元字符时,可以结合不同的模式以展示其作用。以下是不同用法的示例代码:

匹配以 "cat" 开头的单词:

python 复制代码
import re

text = "The cat and the catfish sat on the catwalk."

pattern_starting_with_cat = r'\bcat\w*'
matches_starting_with_cat = re.findall(pattern_starting_with_cat, text)
print("匹配以 'cat' 开头的单词:", matches_starting_with_cat)

这段代码中的 r'\bcat\w*' 匹配以 "cat" 开头的单词。在给定文本中,它会返回以 "cat" 开头的所有单词,例如 "cat", "catfish", "catwalk"。

匹配以 "cat" 结尾的单词:

python 复制代码
pattern_ending_with_cat = r'\b\w*cat\b'
matches_ending_with_cat = re.findall(pattern_ending_with_cat, text)
print("匹配以 'cat' 结尾的单词:", matches_ending_with_cat)

这段代码中的 r'\b\w*cat\b' 匹配以 "cat" 结尾的单词。在给定文本中,它会返回以 "cat" 结尾的所有单词,例如 "cat", "catfish"。

匹配整个单词 "cat":

python 复制代码
pattern_entire_word = r'\bcat\b'
matches_entire_word = re.findall(pattern_entire_word, text)
print("匹配整个单词 'cat':", matches_entire_word)

这段代码中的 r'\bcat\b' 匹配整个单词 "cat"。在给定文本中,它会返回所有独立的 "cat" 单词。

但是它不会返回"catfood"等包含"cat"的单词

运行这些代码将展示 \b 作为单词边界的不同用法,以便更好地理解其功能。

' .' 匹配除'\n'外任意字符

在正则表达式中,. 是一个特殊的元字符,用于匹配除了换行符 \n 之外的任何单个字符。

用法示例:

  1. 匹配任何单个字符: 正则表达式 . 可以匹配任何单个字符,比如字母、数字、标点符号等,除了换行符。

  2. 结合其他模式使用: 可以将. 与其他模式结合使用,比如 a. 可以匹配以字母 "a" 开头,后面跟着任何一个字符的字符串。

  3. 贪婪匹配: . 是贪婪的,它会尽可能多地匹配字符,直到无法匹配为止。

示例:

python 复制代码
import re

text = "The cat sat on the mat."

pattern = r'c.t'  # 匹配以 "c" 开头,后面是任意字符,然后是 "t"
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上述示例中,r'c.t' 这个模式将匹配字符串中以 "c" 开头,后面跟着任意字符,然后以 "t" 结尾的部分。在给定的文本中,匹配到的是 "cat"。

. 是一个非常常用的元字符,用于捕获或匹配大多数的单个字符,但需要注意它不能匹配换行符 \n

*匹配位于 * 之前的字符或者子模式0次或者多次

在正则表达式中,* 是一个量词,用于指示其前面的模式可以出现零次或多次。它表示匹配前面的元素零次或多次。

用法示例:

  • 匹配零次或多次:

    • a* 匹配零个或多个 "a"。
    • ab* 匹配 "a" 后面跟着零个或多个 "b"。例如,"a", "ab", "abb", "abbb", 等等。
  • 贪婪匹配:

    • a*贪婪的,它会尽可能多地匹配 "a",直到无法匹配为止。
  • 结合其他模式使用:

    • 可以将 * 与其他字符结合使用,比如 .* 可以匹配任意数量的任意字符(除了换行符)。

示例:

python 复制代码
import re

text = "The cat sat on the mat."

pattern = r's.*t'  # 匹配以 "s" 开头,后面是零个或多个任意字符,然后以 "t" 结尾
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上述示例中,r's.*t' 这个模式将匹配字符串中以 "s" 开头,后面跟着零个或多个任意字符,最后以 "t" 结尾的部分。在给定的文本中,匹配到的是 "sat" 和 "sat on the mat"。

* 是一个灵活且常用的量词,用于指示匹配其前面的模式零次或多次,以满足灵活的匹配需求。

+ 匹配+ 之前的字符或者子模式 1次或者多次出现

在正则表达式中,+ 是一个量词,用于指示其前面的模式必须至少出现一次或多次。它表示匹配前面的元素至少一次或多次。

用法示例:

  • 匹配一次或多次:

    • a+ 匹配一个或多个 "a"。
    • ab+ 匹配 "a" 后面跟着一个或多个 "b"。例如,"ab", "abb", "abbb", 等等。
  • 贪婪匹配:

    • a+ 是贪婪的,它会尽可能多地匹配 "a",直到无法匹配为止。
  • 结合其他模式使用:

    • 可以将 + 与其他字符结合使用,比如 .+ 可以匹配任意数量的任意字符(除了换行符)。

示例:

python 复制代码
import re

text = "The cat sat on the mat."

pattern = r's.+t'  # 匹配以 "s" 开头,后面是一个或多个任意字符,然后以 "t" 结尾
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上述示例中,r's.+t' 这个模式将匹配字符串中以 "s" 开头,后面跟着一个或多个任意字符,最后以 "t" 结尾的部分。在给定的文本中,匹配到的是 "sat on the mat"。

+ 用于指示至少要有一个或多个其前面的元素出现,使得匹配更具体并要求至少有一次出现。
注意:+ 号会至少匹配一次,但是* 可以至少匹配0次

- 号运算符

在[ ]里面表示范围

python 复制代码
[a-z]//表示小写字母

单单表示连接

- 不用作特殊含义时,它只匹配连字符本身而不具备其他特殊作用。

举例:

假设我们有一个文本字符串 "I have a 5-year-old cat",如果我们使用模式 r'\d+-year-old',这个模式会匹配包含连字符的短语,比如 "5-year-old"。

在这个例子中,- 只是表示连字符,它并没有特殊的匹配行为。

| 或关系

在正则表达式中,| 称为"管道符"或"竖线",它用于表示"或"关系。在正则表达式中,| 用于匹配多个模式中的任何一个。

用法示例:

  • 匹配多个模式之一:

    • cat|dog 匹配包含 "cat" 或 "dog" 中任何一个的字符串。
    • yes|no 匹配包含 "yes" 或 "no" 中任何一个的字符串。
  • 用括号分组:

    • (cat|dog)food 匹配 "catfood" 或 "dogfood"。
    • yes(no|yes) 匹配 "yesno" 或 "yesyes"。

示例:

python 复制代码
import re

text = "I have a cat and a dog."

pattern = r'cat|dog'  # 匹配包含 "cat" 或 "dog" 中任何一个的字符串
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上面的示例中,r'cat|dog' 这个模式将匹配包含 "cat" 或 "dog" 中任何一个的部分。在给定的文本中,匹配到的是 "cat" 和 "dog"。

| 是一个非常有用的元字符,允许同时匹配多个模式中的任何一个,从而提供更灵活的匹配。

^ 规定开头

在正则表达式中,^ 是一个特殊的元字符,用于匹配字符串的开头。

用法示例:

  • 匹配字符串开头: ^pattern 匹配以指定模式 pattern 开头的字符串。
    • 例如,^hello 匹配以 "hello" 开头的字符串。

示例:

python 复制代码
import re

text = "hello world"

pattern = r'^hello'  # 匹配以 "hello" 开头的字符串
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上面的示例中,r'^hello' 这个模式将匹配以 "hello" 开头的字符串。在给定的文本中,由于 "hello" 出现在开头,所以正则表达式匹配到了 "hello"。

^ 在正则表达式中具有锚定作用,它表示匹配字符串的开头位置。

匹配以 前面的字符或者模式结束的字符串

在正则表达式中,$ 是一个特殊的元字符,用于匹配字符串的结尾。

用法示例:

  • 匹配字符串结尾: pattern$ 匹配以指定模式 pattern 结尾的字符串。
    • 例如,world$ 匹配以 "world" 结尾的字符串。

示例:

python 复制代码
import re

text = "hello world"

pattern = r'world$'  # 匹配以 "world" 结尾的字符串
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上面的示例中,r'world$' 这个模式将匹配以 "world" 结尾的字符串。在给定的文本中,由于 "world" 出现在结尾,所以正则表达式匹配到了 "world"。

$ 在正则表达式中具有锚定作用,它表示匹配字符串的结尾位置。

? 的可选择性与改变"贪心性"

在正则表达式中,? 是一个量词,用于指示其前面的模式可以出现零次或一次,表示可选匹配。

用法示例:

  • 匹配零次或一次(也就是选择性):

    • colou?r 匹配 "colour" 或 "color"。在这里,ou? 表示 u 可以出现零次或一次,使得匹配模式更加灵活。
  • 非贪婪匹配:

    • a? 是非贪婪的,它只匹配零次或一次,尽可能少地匹配。
  • 结合其他模式使用:

    • 可以将 ? 与其他字符结合使用,比如 a?b 可以匹配零个或一个 "a",后面跟着 "b"。

示例:

python 复制代码
import re

text = "The colour is red, but color is also acceptable."

pattern = r'colou?r'  # 匹配 "colour" 或 "color"
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

在上述示例中,r'colou?r' 这个模式将匹配 "colour" 或 "color"。在给定的文本中,它匹配到了 "colour" 和 "color",因为 ou? 允许 u 出现零次或一次,使得模式可以匹配两种拼写形式。

改变贪心性

? 紧跟在其他限定符(比如 *, +, {})后面时,它改变限定符的默认贪婪性,使其变为非贪婪或最小匹配。

默认贪婪匹配和非贪婪匹配:

  • 默认情况下,*, +, {} 等限定符是贪婪的:

    • 它们会尽可能多地匹配文本,直到无法匹配为止。
  • 在限定符后添加 ? 将使其变为非贪婪匹配:

    • 这表示它们会尽可能少地匹配文本,只匹配所需的最小字符数。

示例:

python 复制代码
import re

text = "This is a sample sentence for demonstrating non-greedy matching."

# 贪婪匹配
pattern_greedy = r'.+e'
matches_greedy = re.findall(pattern_greedy, text)
print("贪婪匹配:", matches_greedy)

# 非贪婪匹配
pattern_non_greedy = r'.+?e'
matches_non_greedy = re.findall(pattern_non_greedy, text)
print("非贪婪匹配:", matches_non_greedy)

在上述示例中,r'.+e' 是一个贪婪匹配,它会匹配尽可能多的字符直到找到以 "e" 结尾的内容。相反,r'.+?e' 是一个非贪婪匹配,它会尽可能少地匹配字符直到找到以 "e" 结尾的内容。在给定文本中,这两种模式的匹配结果是不同的,一个会匹配更多的内容,另一个会匹配更少的内容。

\ 为转义

在正则表达式中,反斜杠 \ 是一个特殊字符,用于表示后面紧跟着的字符具有特殊含义或具有特定功能。它会改变紧跟其后的字符的解释方式,称为转义字符。

下面是一些常见的用法和特殊含义:

1. 转义特殊字符:

  • 使用 \ 可以让特殊字符失去其特殊含义。比如,. 通常匹配任意字符,但 \. 匹配实际的句点。

2. 匹配特殊字符:

  • \d 匹配一个数字字符。
  • \w 匹配一个字母、数字或下划线字符。
  • \s 匹配任何空白字符(例如空格、制表符、换行符等)。

3. 匹配特定字符:

  • \n 匹配换行符。
  • \t 匹配制表符。
  • \r 匹配回车符。
  • \\ 匹配实际的反斜杠字符。

示例:

假设有以下文本字符串:

python 复制代码
text = "The cat and the hat sat flat on the mat."

import re

pattern = r'\st\w+'  # 匹配以空格开始,后面是字母 "t",然后跟着一个或多个字母、数字或下划线字符的内容
matches = re.findall(pattern, text)
print(matches)

在这个示例中,r'\st\w+' 这个模式会匹配以空格开始,后面是字母 "t",然后跟着一个或多个字母、数字或下划线字符的内容。在给定的文本中,这个模式匹配到的内容是 " the"、 " the".

\num 匹配重复出现字符或者模式

当使用 \num 这种形式的反向引用时,num 代表着之前已经捕获的分组编号。这种引用可以用来匹配之前已经出现的相同模式。以下是两个示例:

示例1:匹配重复的连续数字

假设有字符串:

python 复制代码
text = "1234 1234 5678"

使用正则表达式来匹配重复的连续数字:

python 复制代码
import re

pattern = r'(\d+)\s\1'  # 匹配重复的连续数字
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

示例2:匹配重复的日期格式

假设有字符串:

python 复制代码
text = "Today is 2023-10-10, and tomorrow is 2023-10-10 as well."

使用正则表达式来匹配重复的日期格式:

python 复制代码
import re

pattern = r'(\d{4}-\d{2}-\d{2})\s\1'  # 匹配重复的日期格式
matches = re.findall(pattern, text)
print(matches)  # 输出匹配的内容

这两个示例都使用了 \num 的反向引用,用来匹配先前已经捕获的相同模式。

相关推荐
郭庆汝1 小时前
pytorch、torchvision与python版本对应关系
人工智能·pytorch·python
思则变4 小时前
[Pytest] [Part 2]增加 log功能
开发语言·python·pytest
漫谈网络5 小时前
WebSocket 在前后端的完整使用流程
javascript·python·websocket
try2find6 小时前
安装llama-cpp-python踩坑记
开发语言·python·llama
博观而约取7 小时前
Django ORM 1. 创建模型(Model)
数据库·python·django
精灵vector8 小时前
构建专家级SQL Agent交互
python·aigc·ai编程
Zonda要好好学习9 小时前
Python入门Day2
开发语言·python
Vertira9 小时前
pdf 合并 python实现(已解决)
前端·python·pdf
太凉9 小时前
Python之 sorted() 函数的基本语法
python
项目題供诗9 小时前
黑马python(二十四)
开发语言·python