写点什么

正则表达式中的字符串

作者:向阳逐梦
  • 2022-10-29
    四川
  • 本文字数:1661 字

    阅读完需:约 5 分钟

在使用字符组简记法对电话号码进行匹配的代码如下:

import re
mo = re.search(r"\d\d\d-\d\d\d-\d\d\d\d", "My number is 415-555-4242")
print("Phone number found: " + mo.group())
复制代码

虽然说使用字符组简记法对正则表达式进行了简化,但是我们发现还是有冗余。对于这种冗余可以使用量词来消除。使用量词可以将上面的代码改成如下形式:

import re
mo = re.search(r"\d{3}-\d{3}-\d{4}", "My number is 415-555-4242")
print("Phone number found:" + mo.group())
复制代码

1. 量词的一般形式

通过下面的一些例子大家可以感受下各个量词的用法:

1.1 {n}

import re
mo = re.search(r"a{3}", "aaaa")mo.group()
复制代码

上面代码中的 {3} 指示前面的 a 出现三次。

import re
mo = re.search(r"a{3}", "a")print(mo == None)
复制代码

1.2 {m,n}

import re
mo = re.search(r"a{3,6}", "aaaa")mo.group()
复制代码

上面代码中的 {3,6} 指示前面的 a 最少出现 3 次,最多出现 6 次。在 {3,6} 中,逗号后面不能有空格。

import re
mo = re.search(r"a{3,6}", "aa")print(mo == None)
复制代码

1.3 {m,}

import re
mo = re.search(r"a{3,}", "aaaa")mo.group()
复制代码

上面代码中的 {3,} 指示前面的 a 最少出现 3 次,出现次数没有上限。

import re
mo = re.search(r"a{3,}", "a")print(mo == None)
复制代码

1.4 {,n}

import re
mo = re.search(r"a{,3}", "aaaa")mo.group()
复制代码

上面代码中的 {,3} 指示前面的 a 可以出现,也可以不出现,最多出现 3 次。

import re
mo = re.search(r"a{,3}b", "b")mo.group()
复制代码

2. 常用量词

{m,n} 是通用形式的量词,正则表达式还有三个常用量词,分别是+、?、* 。它们的形态虽然不同于 {m,n},功能却是相同的。

通过下面的一些例子大家可以感受下各个常用量词的用法:

2.1 *

import re
mo = re.search(r"a*b", "aaaab")mo.group()
复制代码

上面代码中的 * 指示前面的 a 可能出现,也可能不出现,出现次数没有上限。

import re
mo = re.search(r"a*b", "b")mo.group()
复制代码

2.2 +

import re
mo = re.search(r"a+b", "ab")mo.group()
复制代码

上面代码中的 + 指示前面的 a 至少出现 1 次,出现次数没有上限。

import re
mo = re.search(r"a+b", "aaaab")mo.group()
复制代码


import re
mo = re.search(r"a+b", "b")print(mo == None)
复制代码

2.3 ?

import re
mo = re.search(r"a?b", "aaab")mo.group()
复制代码

上面代码中的 ? 指示前面的 a 至多出现 1 次,也可能不出现。

import re
mo = re.search(r"a?b", "b")mo.group()
复制代码

3. 滥用点号的问题

因为点号能匹配几乎所有的字符(换行符除外),所以实际应用中许多人图省事,随意使用 .* 或 .+,结果却事与愿违。例如下面例子中的正则表达式不但可以匹配正确的字符串也可以匹配不正确的字符串。

3.1 正确匹配

import re
mo = re.search(r"\".*\"","\"Great hopes\"")mo.group()
复制代码

上面的正则表达式正确匹配了 "Great hopes"。

3.2 不正确匹配

import re
mo = re.search(r"\".*\"","\"Great hopes\" make great men\"")mo.group()
复制代码

当用 .* 来匹配双引号字符串时,不但可以匹配正常的双引号字符串 "Great hopes",还可以匹配格式错误的字符串 "Great hopes" make great men"。这是为什么呢?答案是,正则表达式中的量词分为几类,之前介绍的量词都可以归到一类,叫做匹配优先量词(也叫贪婪量词)。匹配优先量词,顾名思义,就是在拿不准是否要匹配的时候,优先尝试匹配,并且记下这个状态,以备将来“反悔”。为了解决上述问题,正则表达式还提供了忽略优先量词。

4. 忽略优先量词

和匹配优先量词相对应的,正则表达式还提供了忽略优先量词(也叫懒惰量词),如果不确定是否要匹配,忽略优先量词会选择“不匹配”的状态,再尝试表达式中之后的元素,如果尝试失败,再回溯,选择之前保存的匹配的状态。

忽略优先量词只需要在匹配优先量词的后面加上 ?即可。下面使用忽略优先量词再来进行上述字符串的匹配。

import re
mo = re.search(r"\".*?\"","\"Great hopes\"")mo.group()
复制代码


import re
mo = re.search(r"\".*?\"","\"Great hopes\" make great men\"")mo.group()
复制代码

在使用忽略优先量词之后,上面的两段代码都进行了正确的匹配。

发布于: 刚刚阅读数: 4
用户头像

向阳逐梦

关注

人生享受编程,编程造就人生! 2022-06-01 加入

某公司芯片测试工程师,嵌入式开发工程师,InfoQ签约作者,阿里云星级博主,华为云·云享专家。座右铭:向着太阳,追逐梦想!

评论

发布
暂无评论
正则表达式中的字符串_Python_向阳逐梦_InfoQ写作社区