我有一个单词列表,如:
l = """abc
dfg
hij
jih
gfd
cba
cbd
jip
gfe
jiw
cbw"""
我想从这个列表中找到成对的单词, 所以第一个词是:
.(.)(.)
第二个词是:
\2\1.
所以\ 1和\ 2引用第一个单词中的字符。
我能提出的最好的正则表达方式是:
re.findall('(^.(?P<A>.)(?P<B>.)$)(?=.*(^(?P=B)(?P=A).$))', l, re.DOTALL | re.MULTILINE)
但是这个搜索只返回一些对(因为findall只返回非重叠的结果......)。 然后我想到使用正向lookbehind断言,但它们只能用于固定长度的字符串...
有正确的方法吗?
答案 0 :(得分:2)
我怀疑正则表达式是一种很好的方法(特别是在Python中,你不能简单地获得所有可能的匹配字符串的方法,就像在Perl中一样,所以你必须调用findall
在你的字符串的所有前缀)。一个直截了当的选择是:
words = l.split()
pairs = set(frozenset((w1, w2)) for w1 in words for w2 in words
if w1[1:] == w2[1::-1])
结果:
>>> map(tuple, pairs)
[('hij', 'jip'),
('abc', 'cbd'),
('dfg', 'gfd'),
('dfg', 'gfe'),
('jiw', 'hij'),
('hij', 'jih'),
('abc', 'cbw'),
('abc', 'cba')]
你也可以通过在第一遍中保存字典中的单词前缀,然后在第二遍中建立关联来快速解决这个问题:
from collections import defaultdict
prefixes = defaultdict(list)
for w in words:
prefixes[w[1::-1]].append(w)
pairs = set(frozenset((w1, w2)) for w1 in words for w2 in prefixes[w1[1:]])
正则表达式引擎很难超越这种性能。