re.findall只匹配python 3.6中已编译列表中的第一个单词

时间:2018-11-29 21:16:25

标签: regex python-3.x regex-lookarounds

我有一个城市名称列表,我正在尝试使用python匹配给定字符串中的名称。 例如 我的字串->'142法郎开车去羚羊溪北达科他州125' 其中“羚羊溪” =城市名称(来自“数据框”城市列),还有一个名为“羚羊”和“羚羊湖”的城市

我正在使用re.findall方法查找所有匹配项。执行以下re.findall(重新编译的城市列表,我的字符串)后。它的输出仅为“羚羊”,而不是{“羚羊”} {“羚羊溪”}和{“羚羊湖”}。另外,如果我从编译列表中删除“羚羊”。它的输出为{'Antelope Creek'},而不是{'Antelope Creek'}和{'Antelope Lake'}。好像findall只匹配第一个单词。请给我建议使用re.findall查找所有匹配项的任何解决方案。我将在下面附加我的代码。

my string - '142 franc drive apt 125 Antelope Creek North Dakota' 
pattern = r'\b({0})\b'.format('|'.join(All_city_names.tolist()))
p = re.compile(pattern)
all_values = p.findall(my string)
cities = [tuple(j for j in i if j)[-1] for i in all_values] (%as it is a tuple format)

2 个答案:

答案 0 :(得分:0)

包含|的正则表达式模式将从左到右,并在与模式匹配时立即停止,忽略其余部分。如果要匹配列表中的所有城市,则必须分别匹配所有城市。

简单的部分非正则表达式解决方案

all_values = [city for city in All_city_names.tolist() if city in my_string]

更长的正则表达式解决方案

all_values = [city for city in All_city_names.tolist() if re.search(r'\b' + re.escape(city) + r'\b', my_string)]

答案 1 :(得分:0)

正则表达式本身从左到右执行。

这意味着,如果您在一组轮换中有一个列表,则第一个轮换
该匹配项将导致引擎移过轮换组并
继续尝试匹配正则表达式的其余部分。

如果您的列表产生了这样的正则表达式\b(Antelope|Antelope Creek|Antelope Lake)\b

您会看到,只有 Antelope 会被给予匹配的机会。

要解决此问题,您必须 排序 以正则表达式前的“降序” 列表
被建造。

这样做将产生以下正则表达式:

\b(Antelope Lake|Antelope Creek|Antelope)\b

由于最长(排序的)子字符串位于开头,因此引擎现在有机会匹配其他替换。