如何在Python迭代器中匹配对象模式?
使用Python的re函数来匹配和处理文本中的模式非常简单,比如:
re.match('a[efg]*c', 'aggggc')
那么,如何在列表或其他Python迭代器上做到同样的事情呢?比如,我可能有一个这样的列表:
>>> list = ['foo', 'bar', 3, (1, 2, 3), 'a', 'b', {5, 6, 7}, 'apple']
接下来,按照正则表达式的习惯,我可能想要匹配一个这样的模式:
>>> pattern = ['a', '[', {7, 6, 5}, 'b', 'c', ']', '*', 'apple']
我想在这个列表中找到一个匹配项。如果是正则表达式,我会这样写:
>>> match = re.search(pattern, list)
>>> match.group(0)
['a', 'b', {5, 6, 7}, 'apple']
但当然,这样不行,因为Python的正则表达式期望看到的是字符串。
那我该怎么做呢?
注意:我想要的是匹配模式的能力,而不是这个具体的语法。我想,理想的答案应该是一个模块或库(或者简洁的函数),提供多种正则表达式风格的模式匹配工具,能够在列表上使用。
我为什么想要这个的解释:我正在编写处理东南亚语言文本的脚本,这些语言使用复杂的文字。现在我正在做的程序会智能地纠正打字错误(这个语言有些字符可以在上面、下面、前面、周围等位置,并且有特定的规则来决定它们的顺序)。我程序的第一步使用状态机将每个字符分配到一个类别,比如辅音、元音、声调、数字等等。第二步会尝试纠正无效的音节和其他类型的错误。就音节部分而言,英语没有类似的东西,但在数字方面,比如我看到模式['number', 'o', 'number']
,那么我会推测打字者是想说'零'而不是'哦',并进行适当的纠正。
2 个回答
0
通常情况下,你需要写一个函数来检查这个问题。可以像下面这样写。
import sys
my_list = ['foo', 'bar', 3, (1, 2, 3), 'a', 'b', {5, 6, 7}, 'apple']
pattern = ['fo', 'bar', 3, (1, 2, 3), 'a', '*', {5, 6, 7}, 'apple']
if len(my_list) != len(pattern):
print('List length dose not match with the pattern')
sys.exit(1)
for offset,value in enumerate(my_list):
if pattern[offset] != value and pattern[offset] != '*':
print('Pattern matching failed at offset {} with value {}'.format(offset, my_list[offset]))
break;
else:
print('Pattern matched perfectly..');
0
你可以这样做,先检查一下这个东西是不是一个 str
(字符串),再去尝试匹配它。
import re
from collections import Iterable
pattern = re.compile('a[efg]*')
items = ['foo', 'bar', 3, (1, 2, 3), 'a', 'b', {5, 6, 7}, 'apple']
def _find_matches(it, pattern):
matches = []
for i in it:
if isinstance(i, str):
m = pattern.match(i)
if m:
matches.append(m)
elif isinstance(i, Iterable):
m = _find_matches(i, pattern)
matches.extend(m)
else:
print "Could not process: {}".format(i)
return matches
results = _find_matches(items, pattern)