正则表达式

1.小例子

例:在文本中找指定的单词study

\bstudy\b

例:在文本中找指定的一句话,指定开头单词we,和结尾单词you

\bwe\b.*\byou\b

正则表达式测试工具,推荐 match tracer

http://www.regexlab.com/download/?/mtracer/MTracer.zip

2.常用元字符

元字符的作用:匹配字符,匹配位置,匹配数量,匹配模式。

以下是一些常用的正则表达式元字符:

  1. .: 匹配除换行符以外的任意一个字符。
  2. ^: 匹配输入字符串的开始位置。
  3. $: 匹配输入字符串的结束位置。
  4. *: 匹配前面的字符(或子表达式)零次或多次。
  5. +: 匹配前面的字符(或子表达式)一次或多次。
  6. ?: 匹配前面的字符(或子表达式)零次或一次。
  7. []: 字符类,匹配括号内的任意一个字符。
  8. |: 逻辑 OR 操作符,用于匹配两个选择之一。
  9. (): 分组,将其中的内容视为一个整体。
  10. \: 转义字符,用于转义元字符。
  11. \b:匹配单词的开始或结束
  12. \d:匹配数字
  13. \w:匹配字母,数字,下划线或汉字
  14. \s:匹配任意空白字符,包括空格、制表符和换行符等

例:从下面字符串中找到But200和s100的正则表达式

But200 a man is not made for defeat. A man can be destroyed but not defeated. s100

(1)^But\d*

(2)s\d*$

3.字符转义

        在正则表达式中,有一些特殊字符具有特殊的含义。如果你想要匹配这些特殊字符本身而非它们的特殊含义,你需要进行字符转义。在正则表达式中,使用反斜杠 \ 来进行字符转义。

下面是一些常见的需要进行字符转义的特殊字符:

  • .*+?[](){}^$\|: 这些字符在正则表达式中具有特殊含义,如果你想匹配它们本身,需要在前面加上反斜杠进行转义。
  • \d\w\s: 这些是用于匹配数字、单词字符和空白字符的字符类别简写。如果你想匹配它们本身,也需要进行转义,如 \\d\\w\\s

例如,如果你想匹配一个句子中的句号 .,你可以使用正则表达式 \. 进行转义。同样地,如果你想匹配一个数字字符 \d,你可以使用 \\d 进行转义。

4.匹配重复的限定符

在正则表达式中,重复限定符用于指定前面的字符或子表达式可以重复出现的次数。以下是一些常见的重复限定符:

  1. *:匹配前面的字符(或子表达式)零次或多次。
  2. +:匹配前面的字符(或子表达式)一次或多次。
  3. ?:匹配前面的字符(或子表达式)零次或一次。
  4. {n}:匹配前面的字符(或子表达式)恰好 n 次。
  5. {n,}:匹配前面的字符(或子表达式)至少 n 次。
  6. {n,m}:匹配前面的字符(或子表达式)至少 n 次,但不超过 m 次。

例:匹配worlllld

\bworl{3,5}d\b

例:匹配we1

we\d?

5.字符集

正则表达式字符集用于指定一个字符集合,可以匹配其中的任意一个字符。你可以使用方括号 [] 来定义一个字符集,如下所示

[abc]      // 匹配 a、b 或 c 中的任意一个字符
[a-z]      // 匹配任意小写字母
[A-Z]      // 匹配任意大写字母
[0-9]      // 匹配任意数字字符
[^\w]      // 匹配任意非单词字符(即除了字母、数字和下划线之外的字符)

在字符集中,你可以使用连字符 - 指定一个范围。例如,[a-z] 可以匹配任意一个小写字母,而 [0-9] 可以匹配任意一个数字字符。

如果你想匹配一个特定的字符集合,但是其中包含了正则表达式中的特殊字符,你需要进行字符转义。例如,如果你想匹配字符集合 [+.()] 中的任意一个字符,你可以使用以下正则表达式:

[+\.\(\)]

注意,字符集合中的重复出现的字符只会被匹配一次。例如,[hello] 只会匹配单词 hello 中的每个字符一次。如果你想匹配重复出现的字符,你需要使用重复限定符。

6.分歧条件

        在正则表达式中,你可以使用分支条件(alternation)来匹配多个模式中的任意一个。分支条件使用竖线 | 来分隔不同的模式,如下所示:

pattern1|pattern2|pattern3

        这个表达式会先尝试匹配 pattern1,如果匹配成功,则匹配过程停止。如果没有匹配成功,则继续尝试匹配 pattern2,然后是 pattern3,依此类推。

例如,假设你想匹配字符串中的 "apple" 或 "orange",你可以使用以下正则表达式:

apple|orange

        这样,如果字符串中包含 "apple" 或 "orange" 中的任意一项,正则表达式就会匹配成功。

分支条件还可以与其他正则表达式元字符和限定符结合使用,以构建更复杂的模式。例如:

\d{3}-\d{3}-\d{4}|(\(\d{3}\))?\s?\d{3}-\d{4}

        这个正则表达式匹配电话号码,可以接受以下两种格式:xxx-xxx-xxxx 或 (xxx) xxx-xxxx。其中,分支条件 (xxx) 是可选的。

使用分支条件可以灵活地处理多个匹配模式,方便地实现复杂的匹配需求。

7.分组

        在正则表达式中,分组是将模式的一部分括在圆括号 ( ) 中的一种机制。它可以用于多种目的,包括限定符应用范围、捕获匹配内容和创建子模式等。

下面是几个使用分组的示例:

        (1)限定符应用范围:

(abc){3}

这个表达式表示匹配连续出现三次的 "abc"。分组 (abc) 中的限定符 {3} 仅适用于整个分组,而不是单独的字符。

        (2)捕获匹配内容:

(\w+)\s(\w+)

这个表达式表示匹配由一个或多个字母数字字符组成的单词,然后是一个空白字符,然后是另一个由一个或多个字母数字字符组成的单词。分组 (\w+) 将捕获匹配到的内容供后续处理使用。

        (3)子模式:

(a|b|c)\d

        这个表达式表示匹配以 "a"、"b" 或 "c" 开头,后跟一个数字的字符串。分组 (a|b|c) 创建了一个子模式,表示从这三个选项中选择一个进行匹配。

分组还可以与其他正则表达式元字符和限定符结合使用,以构建更复杂的模式。你可以根据具体的匹配需求来选择是否使用分组。

        常用的分组形式:

        (1)捕获分组:使用圆括号 ( ) 表示,可以将匹配到的内容保存到一个变量中,后续可以通过这个变量进行操作。

import re

# 匹配以数字开头和结尾的字符串,并提取其中的数字
s = 'abc123def'
pattern = r'(\d+)'
match = re.search(pattern, s)
print(match.group(1))  # 输出结果为 '123'

        (2)非捕获分组:使用 (?: ) 表示,与捕获分组类似,但不会将匹配到的内容保存到一个变量中,因此不消耗额外的内存空间。

import re

# 匹配多个连续的单词,其中每个单词之间由空格分隔
s = 'hello world   python java'
pattern = r'(?:\w+\s+){3}'
match = re.search(pattern, s)
print(match.group(0))  # 输出结果为 'hello world   python '

         (3)正向肯定预查:使用 (?= ) 表示,表示必须满足括号中的条件,但不会将其作为匹配结果返回。

import re

# 匹配以 hello 开头,后面跟着一个数字或字母,并以 world 结尾的字符串
s = 'hello1 world'
pattern = r'hello(?=\w)world'
match = re.search(pattern, s)
print(match.group(0))  # 输出结果为 'hello1 world'

        (4)正向否定预查:使用 (?! ) 表示,表示必须不满足括号中的条件,但不会将其作为匹配结果返回。

import re

# 匹配不以 hello 开头的字符串
s = 'world'
pattern = r'^(?!hello).*$'
match = re.search(pattern, s)
print(match.group(0))  # 输出结果为 'world'
 8.反义

在正则表达式中,可以使用 ^ 符号来表示反义,即匹配不符合指定模式的内容。^ 符号在不同的位置会有不同的含义:

  1. 在字符集 [ ] 中,^ 表示取反操作,用于匹配不在字符集中的字符。例如,[^a] 表示匹配除了字母 "a" 之外的任意字符。

  2. 在正则表达式的开头,^ 表示匹配字符串的开始位置。例如,^abc 表示匹配以 "abc" 开头的字符串。

  3. 在其他位置,^ 表示反义,用于匹配不符合指定模式的内容。例如,\d 表示匹配数字,而 \D 表示匹配非数字的字符。

下面是一些常用的反义符号及其含义:

  • \d: 匹配数字字符 (0-9)。\D 匹配非数字字符。
  • \w: 匹配字母、数字或下划线。\W 匹配非字母、数字或下划线字符。
  • \s: 匹配空白字符。\S 匹配非空白字符。

通过使用反义符号,你可以更精确地定义你需要匹配的内容,甚至找到与特定模式不匹配的内容。

9.后向引用

        当你在正则表达式中使用括号来创建一个分组时,这个分组内匹配到的内容会被保存供以后使用。后向引用就是指向这些保存的内容的引用

        在正则表达式中,后向引用可以通过 \1, \2, \3 等来表示。这些符号分别对应着第一个、第二个、第三个括号内匹配到的内容。例如,如果你的正则表达式是 (\w)+\s\1,它将会匹配重复的单词,其中 \1 将会引用第一个括号内匹配到的内容。

下面是一个更详细的示例:

假设我们要匹配连续出现的相同单词,我们可以使用后向引用来实现。下面是一个简单的例子:

import re

pattern = r'\b(\w+)\s+\1\b'
text = "hello hello world world"
matches = re.findall(pattern, text)
for match in matches:
    print("Match found:", match)

        在这个例子中,我们使用了 \b(\w+)\s+\1\b 作为正则表达式。这个表达式的含义是:\b 匹配单词边界,(\w+) 匹配一个或多个字母数字字符(即单词),\s+ 匹配一个或多个空白字符,然后 \1 引用前面捕获到的内容,最后的 \b 匹配单词边界。这样我们就能够匹配连续出现的相同单词了。

后向引用提供了一种强大的方式来引用先前捕获到的内容,从而使得我们可以更灵活地进行匹配和操作。

10.零宽断言

        正则表达式的零宽断言是一种特殊的模式匹配技术,用于指定匹配位置而不消耗实际的字符

        (1)正向先行断言(Positive Lookahead Assertion):匹配某个位置后面紧跟着指定的模式。
import re
pattern = r'\d+(?= dollars)'
text = 'I have 100 dollars in my pocket'
result = re.search(pattern, text)
print(result.group(0))  # 输出: '100'

        当我们使用正则表达式进行匹配时,有时候我们希望只匹配某个位置后面紧跟着指定模式的情况,而不包括该模式本身。这就是正向先行断言(Positive Lookahead Assertion)的作用。

让我们逐行解释这段代码的含义:

  1. import re:导入 Python 的正则表达式模块。

  2. pattern = r'\d+(?= dollars)':定义一个正则表达式模式。该模式使用了零宽度正向先行断言,\d+表示匹配一串数字,(?= dollars)表示该数字后面必须紧跟着一个空格和单词"dollars"。

  3. text = 'I have 100 dollars in my pocket':待匹配的文本。

  4. result = re.search(pattern, text):使用 re.search() 函数在文本中搜索符合模式的字符串。

  5. print(result.group(0)):打印匹配结果的第一个分组。

当使用re.search()函数搜索这个模式时,会成功匹配到"100"这个数字,而不包括"dollars"这个单词。所以最终的输出是'100'。

简单来说,这段代码使用了正向先行断言,通过在匹配模式中添加 (?=...) 来指定一个位置后面必须紧跟着某个模式,从而实现精确匹配。在这个例子中,我们成功匹配到了文本中的 "100",而不是整个 "100 dollars"。

        (2)负向先行断言(Negative Lookahead Assertion):匹配某个位置后面不紧跟着指定的模式。
import re
pattern = r'\d+(?! dollars)'
text = 'I have 100 euros in my wallet'
result = re.search(pattern, text)
print(result.group(0))  # 输出: '100'
         (3)正向后顾断言(Positive Lookbehind Assertion):匹配某个位置前面紧跟着指定的模式。
import re
pattern = r'(?<=\$)\d+'
text = 'The price is $100'
result = re.search(pattern, text)
print(result.group(0))  # 输出: '100'

        当我们使用正则表达式进行匹配时,有时候我们希望只匹配某个位置前面紧跟着指定模式的情况,而不包括该模式本身。这就是正向后顾断言(Positive Lookbehind Assertion)的作用。

下面是代码的详细解析:

  1. import re:导入 Python 的正则表达式模块。

  2. pattern = r'(?<=\$)\d+':定义一个正则表达式模式。该模式使用了零宽度正向后顾断言,(?<=\$)表示要匹配的数字前面必须紧跟着一个美元符号"$",\d+表示匹配一串数字。

  3. text = 'The price is $100':待匹配的文本。

  4. result = re.search(pattern, text):使用 re.search() 函数在文本中搜索符合模式的字符串。

  5. print(result.group(0)):打印匹配结果的第一个分组。

运行这段代码,输出结果是 '100',即匹配到了文本中的 "100",但不包括 "$" 这个符号。

简单来说,这段代码使用了正向后顾断言,通过在匹配模式中添加 (?<=...) 来指定一个位置前面必须紧跟着某个模式,从而实现精确匹配。在这个例子中,我们成功匹配到了文本中的 "100",而不包括 "$" 这个符号。

        (4)负向后顾断言(Negative Lookbehind Assertion):匹配某个位置前面不紧跟着指定的模式。
import re
pattern = r'(?<!\$)\d+'
text = 'The price is 100 dollars'
result = re.search(pattern, text)
print(result.group(0))  # 输出: '100'

         这段代码使用了正则表达式来匹配文本中不以美元符号"$"作为前导的连续数字。让我来详细解释一下:

  1. import re:导入 Python 的正则表达式模块。

  2. pattern = r'(?<!\$)\d+':定义一个正则表达式模式。该模式使用了零宽度负向后顾断言(?<!\$),表示要匹配的数字前面不能紧跟着美元符号"$",\d+表示匹配一串数字。

  3. text = 'The price is 100 dollars':待匹配的文本。

  4. result = re.search(pattern, text):使用re.search()函数在文本中搜索符合模式的字符串。

  5. print(result.group(0)):打印匹配结果的第一个分组。

当运行这段代码时,由于模式(?<!\$)\d+要求匹配的数字前面不能紧跟着美元符号"$",因此它会匹配到文本中的 "100",因为 "100" 前面并没有美元符号。

因此,最终输出结果是 '100',即成功匹配到了文本中的 "100"。

总结:通过使用零宽度负向后顾断言(?<!\$),这段代码实现了匹配文本中不以美元符号"$"作为前导的数字。

11.注释

         在正则表达式中,(?#comment) 是一种注释的方式,可以用于在正则表达式中添加注释而不会影响匹配的行为。这种注释方式不同于使用 re.VERBOSE 标记的多行注释,而是直接在正则表达式中插入单行注释。

        当使用正则表达式中的 (?#comment) 时,(?#comment) 是一个注释,不会对匹配产生影响,它可以用来在正则表达式中添加注释以提高可读性。

以下是一个简单的示例,演示如何在正则表达式中使用 (?#comment) 进行注释

import re

# 匹配 email 地址的正则表达式,包括用户名和域名部分
pattern = re.compile(r'''
    [\w\.-]+                   # 匹配用户名部分
    @                           # @ 符号
    [\w\.-]+                   # 匹配域名部分
    (?#comment: 这是一个简单的 email 地址匹配正则表达式)
''', re.VERBOSE)

text = "example@example.com"
result = pattern.match(text)
if result:
    print(result.group())  # 输出:'example@example.com'

        首先我们定义了一个正则表达式模式,使用了 Python 中的 re.compile 方法将其编译为一个正则表达式对象。在这个模式中,我们使用了 re.VERBOSE 标志,它允许我们在正则表达式中添加注释和空白符,以提高可读性。

正则表达式模式如下所示:

'''
[\w\.-]+                   # 匹配用户名部分
@                           # @ 符号
[\w\.-]+                   # 匹配域名部分
(?#comment: 这是一个简单的 email 地址匹配正则表达式)
'''

现在让我们逐行解析这个正则表达式模式:

  1. [\w\.-]+:这部分匹配 email 地址中的用户名部分。[\w\.-] 表示匹配单个字母、数字、下划线、句点或连字符,+ 表示匹配前面的字符至少一次。

  2. @:这部分匹配 email 地址中的 @ 符号。

  3. [\w\.-]+:这部分匹配 email 地址中的域名部分,规则与用户名部分相似。

  4. (?#comment: 这是一个简单的 email 地址匹配正则表达式):这是一个注释,不会对匹配产生影响,只是用来解释正则表达式的作用。

然后我们使用 pattern.match(text) 方法尝试在给定的文本中找到匹配正则表达式模式的部分。如果找到了匹配,就会返回一个匹配对象;否则返回 None。

最后,我们检查是否找到了匹配,如果找到了,则打印匹配的部分。

在这个示例中,由于文本 "example@example.com" 符合我们定义的 email 地址模式,因此会成功匹配,并打印出 "example@example.com"。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值