02-不用正则表达式来查找文本模式
7.1 不用正则表达式来查找文本模式
假设你希望在字符串中查找电话号码。你知道模式:3个数字+一个短横线+3个数字+一个短横线+4个数字,如415-555-4242。
假定我们用一个名为 isPhoneNumber()
的函数来检查字符串是否匹配模式,它返回 True
或 False
。打开一个新的文件编辑器窗口,输入以下代码,然后保存为isPhoneNumber.py:
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()
函数进行了几项检查,看看 text
中的字符串是不是有效的电话号码。如果其中任意一项检查失败,函数就返回 False
。函数首先检查该字符串是否刚好有12个字符❶。然后它检查区号(就是 text
中的前3个字符)是否只包含数字❷。函数剩下的部分检查该字符串是否符合电话号码的模式:号码必须在区号后出现第一个短横线❸,3个数字❹,然后是另一个短横线❺,最后是4个数字❻。如果程序执行通过了所有的检查,它就返回True❼。
用参数 '415-555-4242'
调用 isPhoneNumber()
将返回 True
。用参数 'Moshi moshi'
调用 isPhoneNumber()
将返回 False
,这项测试失败了,因为不是12个字符。
如果想在更长的字符串中寻找电话号码,就必须添加更多代码来寻找电话号码模式。用下面的代码替代isPhoneNumber.py中的最后4个 print()
函数调用:
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
循环的每一次迭代中,取自 message
的一段新的12个字符被赋给变量 chunk
❶。例如,在第一次迭代时, i
是0, chunk
被赋值为 message[0:12]
(即字符串 'Call me at 4'
)。在下一次迭代时, i
是1, chunk
被赋值为 message[1:13]
(即字符串 'all me at 41'
)。换言之,在 for
循环的每次迭代中, chunk
取以下的值:
'Call me at 4'
'all me at 41'
'll me at 415'
'l me at 415-'
- ……
将 chunk
传递给 isPhoneNumber()
,看看它是否符合电话号码的模式❷。如果符合,就输出这段文本。
继续遍历 message
,最终 chunk
中的12个字符会是一个电话号码。该循环遍历了整个字符串,测试了每一段12个字符,输出所有满足 isPhoneNumber()
的 chunk
。当我们遍历完 message
,就输出 Done
。
虽然在这个例子中 message
中的字符串很短,但它也可能包含上百万个字符,程序运行仍然不需要1秒。使用正则表达式编写查找电话号码的类似程序,运行也不会超过1秒,但用正则表达式编写这类程序会快得多。