正则表达式 (20)

Posted 怪兽宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式 (20)相关的知识,希望对你有一定的参考价值。

正则表达式简介

  • 您可能会熟悉通过按CTRL-F键入您要查找的单词来搜索文本。正则表达式更进一步:它们允许您指定要搜索的文本模式。您可能不知道商家的确切电话号码,但如果您住在美国或加拿大,您将知道它将是三位数字,后跟一个连字符,然后再输入四位数字(可选地,三位数的区号开始)。这是当你看到它:415-555-1234,你就知道他是一个电话号码,但4,155,551,234不是。
  • 正则表达式是有帮助的,但是即使大多数现代文本编辑器和文字处理器(如Microsoft Word或OpenOffice)都可以找到可以基于正则表达式进行搜索的查找和替换功能,非程序员也不会不知道这些表达式。事实上,科技作家Cory Doctorow认为即使在教学编程之前,我们也应该先教正式表达式:

    “知道[正则表达式]可以意味着解决问题的三个步骤与3,000个步骤之间的差异。当你是一个书呆子的时候,你不知道通过几次敲击键盘才能解决的问题,可能会让其他人厌烦,而且容易出错。“

没有正则表达式的文本模式

我们使用一个名为isPhoneNumber()的函数来检查一个字符串是否匹配此模式,返回True或False。

 def isPhoneNumber(text):
    if len(text) != 12:
        return False
    for i in range(0, 3):
        if not text[i].isdecimal():
            return False
    if text[3] != '-':
        return False
    for i in range(4, 7):
        if not text[i].isdecimal():
            return False
    if text[7] != '-':
        return False
    for i in range(8, 12):
        if not text[i].isdecimal():
            return False
    return True

print('415-555-4242 is a phone number:')
print(isPhoneNumber('415-555-4242'))
print('Moshi moshi is a phone number:')
print(isPhoneNumber('Moshi moshi'))

415-555-4242 is a phone number:
True
Moshi moshi is a phone number:
False

    • isPhoneNumber()函数具有执行几个检查的代码,以查看文本中的字符串是否是有效的电话号码。如果任何这些检查失败,该函数返回False。首先代码检查字符串正好是12个字符。然后它检查区域代码(即文本中的前三个字符)只包含数字字符。功能的其余部分检查字符串是否符合电话号码的格式:该号码必须有区号后的第一个连字符,三个数字字符,另一个连字符,最后还有四个数字。如果程序执行设法通过所有检查,则返回True。
  • 您将不得不添加更多的代码来在更大的字符串中找到这种文本模式。用以下内容替换isPhoneNumber.py中的最后四个print()函数调用:

 def isPhoneNumber(text):
    if len(text) != 12:
        return False
    for i in range(0, 3):
        if not text[i].isdecimal():
            return False
    if text[3] != '-':
        return False
    for i in range(4, 7):
        if not text[i].isdecimal():
            return False
    if text[7] != '-':
        return False
    for i in range(8, 12):
        if not text[i].isdecimal():
            return False
    return True

message = 'Call me at 415-555-1011 tomorrow. 415-555-9999 is my office.'
for i in range(len(message)):
    chunk = message[i:i+12]    #❶
    if isPhoneNumber(chunk):   #❷
        print('Phone number found: ' + chunk)
print('Done')

Phone number found: 415-555-1011
Phone number found: 415-555-9999
Done

    • 在for循环的每次迭代中,将来自消息的12个字符的新块分配给变量块❶。例如,在第一次迭代中,我是0,并且chunk被分配了消息[0:12](即,字符串’Call me at 4’)。在下一次迭代中,我是1,并且块被分配消息[1:13](字符串’Call me at 41’)。
    • 您将块传递到isPhoneNumber()以查看它是否匹配电话号码模式❷,如果是,则打印该块。
    • 继续循环通过消息,最终组块中的12个字符将是一个电话号码。循环遍历整个字符串,测试每个12个字符的部分,并打印发现满足isPhoneNumber()的任何块。完成消息后,我们打印完成。
  • 虽然在这个例子中消息中的字符串很短,但它可能是数百万个字符,并且该程序仍将在不到一秒钟内运行。使用正则表达式查找电话号码的类似程序也将在不到一秒钟内运行,但正则表达式可以更快地编写这些程序。

用正则表达式寻找文本的模式

  • 上面的电话号码查找程序能够工作,但它使用大量的代码来做某些限制:isPhoneNumber()函数是17行,但只能找到一个模式的电话号码。一个格式如415.555.4242或(415)555-4242的电话号码呢?如果电话号码有一个扩展名,如415-555-4242 x99怎么办? isPhoneNumber()函数将无法验证它们。您可以为这些附加模式添加更多代码,但有一种更简单的方法。
  • 正则表达式,简称为正则表达式,是文本模式的描述。例如,正则表达式中的\ d表示数字字符,即任何单个数字0到9;正则表达式\ d \ d \ d- \ d \ d \ d- \ d \ d \ d \ d使用Python来匹配以前的isNumber()函数做的相同文本:一个三个数字的字符串,一个连字符,三个数字,另一个连字符和四个数字。
  • 但正则表达式可以更加复杂。例如,在一个模式之后添加一个3的大括号({3}),就像说“匹配这个模式三次”。所以稍微更短的regex \ d {3} - \ d {3} - \ d {4 }也匹配正确的电话号码格式。

创建正则表达式对象

Python中的所有正则表达式函数都在re模块中。

import re

注意:

  • 将表示正则表达式的字符串值传递给re.compile()会返回一个正则表达式模式对象(或者简单地说是一个正则表达式对象)。
  • 要创建与电话号码模式匹配的正则表达式对象,请输入以下内容。( 记住\ d表示“一个数字字符”,\ d \ d \ d- \ d \ d \ d- \ d \ d \ d \ d是正确的电话号码模式的正则表达式。)
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
  • 现在phoneNumRegex变量包含一个Regex对象。
  • 请记住,Python中的转义字符使用反斜杠(\)。字符串值“\ n”表示单个换行符,而不是反斜杠后跟小写字母n。您需要输入转义字符\以打印单个反斜杠。所以’\ n’是表示反斜杠后跟小写字母n的字符串。但是,通过在字符串值的第一个引用之前放置一个r,您可以将字符串标记为原始字符串,不会转义字符。
  • 由于正则表达式经常在其中使用反斜杠,因此将原始字符串传递到re.compile()函数,而不是输入额外的反斜杠是方便的。
    输入r'\d\d\d-\d\d\d-\d\d\d\d' 比 输入'\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d'更容易。

    匹配正则表达式对象

    正则表达式对象的search()方法搜索传递给正则表达式的任何匹配的字符串。如果在字符串中找不到正则表达式,则search()方法将返回None。如果找到该模式,则search()方法返回一个Match对象。匹配对象具有一个group()方法,它将从搜索的字符串中返回实际匹配的文本。 (我稍后会解释一下。)

    phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
    mo = phoneNumRegex.search('My number is 415-555-4242.')
    print('Phone number found: ' + mo.group())

    Phone number found: 415-555-4242

    • mo变量名只是用于Match对象的通用名称。这个例子首先可能看起来很复杂,但是比以前的isPhoneNumber.py程序要短得多,做的也是一样的。
    • 在这里,我们将所需的模式传递给re.compile(),并将所产生的Regex对象存储在phoneNumRegex中。然后我们在phoneNumRegex上调用search(),并传递search()我们要搜索匹配的字符串。搜索结果存储在变量mo中。在这个例子中,我们知道我们的模式将在字符串中找到,所以我们知道一个Match对象将被返回。知道mo包含一个Match对象而不是null值None,我们可以在mo上调用group()来返回匹配。在我们的打印声明中写入mo.group()显示整个匹配,415-555-4242。

正则表达式匹配的回顾

  • 虽然在Python中使用正则表达式有几个步骤,但每个步骤都相当简单。
  1. import re导入正则表达式模块。
  2. 使用re.compile()函数创建一个正则表达式对象。 (记住使用原始字符串。)、
  3. 将要搜索的字符串传递到正则表达式对象的search()方法中。这返回一个Match对象
  4. 调用Match对象的group()方法返回一个实际匹配文本的字符串。