gpt4 book ai didi

python - 在 Python 中使用原子分组的最佳方式?

转载 作者:行者123 更新时间:2023-12-05 06:01:28 25 4
gpt4 key购买 nike

所以我写了这个,这太可怕了:

def parse_results(string):
space = r"([\s\t]{0,5})"
building_type = r"(([Uu]nit|[Ss]tudio|[Ff]lat)?)"
street_type = (r"((\d+)(\&|\-)*(\d*)(\w*)(\w*)(\s*)(\w*)(\s*)(\w*)(\s*)"
r"([Ee]nd|[Gg]reen|[Cc]auseway|[Cc]heapside|[Cc]rescent|"
r"[Ss]treet|[Ll]ane|[Ww]alk|[Rr]oad|[Aa]venue|[Dd]rive|"
r"[Pp]ark|[Ww]ay|[Pp]lace|[Pp]arade|[Ii]ndustrial"
r"[Ee]state|[Tt]rading [Ee]state|[Hh]ouse|[Gg]reen))")
line_1 = r"(\w*)"
line_2 = r"(\w*)"
line_3 = r"(\w*)"
line_4 = r"(\w*)"
line_5 = r"(\w*)"
postcode = r"(([A-Z0-9][A-Z0-9][A-Z0-9]?[A-Z0-9]? {1,2}[0-9][A-Z]{2}))"
pattern = re.compile(rf"({building_type}{space}{street_type}{space}"
rf"{line_1}{space}{line_2}{space}{line_3}{space}"
rf"{line_4}{space}{line_5}{space}{postcode})")
try:
matches = pattern.finditer(string)
for match in matches:
address = re.sub(r"\s+", r" ", match.group(1))
return address
except Exception as e:
return (f"Error looking for address, exception {e}")

它的目的是在我用于机器学习训练的大型文本语料库中查找英国地址。然而,由于 backtracking,它慢得无法使用。 .

经过研究,解决方案似乎是使用原子分组,类似于在 Ruby 中的做法。

Python RE 模块不支持开箱即用,但是有一些解决方法,例如:

Do Python regular expressions have an equivalent to Ruby's atomic grouping?

显然有一个 Python Regex确实支持开箱即用的 atomix 分组的模块,但似乎几乎没有人在教程中谈论它。

两个问题:

  1. 哪种方法最好? RE 模块变通还是 Regex 模块?

  2. 有人可以指出示例的方向,以便我可以为我的用例解决这个问题吗?

谢谢!

最佳答案

无论您使用的是 re 还是 regex,您都必须修复您的模式,因为它是 catastrophic backtracking易于。这里不需要原子分组,您需要具有强制模式的可选分组。此外,您需要修复可能在字符串内的相同位置开始匹配的交替。

你可以使用

(?:[Uu]nit|[Ss]tudio|[Ff]lat)?\s{0,5}\d+[&-]*\w*\s*(?:[Ee]nd|[Gg]reen|[Cc]auseway|[Cc]heapside|[Cc]rescent|[Ss]treet|[Ll]ane|[Ww]alk|[Rr]oad|[Aa]venue|[Dd]rive|[Pp]ark|[Ww]ay|[Pp]lace|[Pp]arade|[Ii]ndustrial[Ee]state|[Tt]rading [Ee]state|[Hh]ouse|[Gg]reen)(?:\s{1,5}\w+){0,5}\s{0,5}[A-Z0-9][A-Z0-9][A-Z0-9]?[A-Z0-9]? {1,2}[0-9][A-Z]{2}

参见 regex demo .

参见 Python demo :

import re

def parse_results(string):
space = r"\s{0,5}"
building_type = r"(?:[Uu]nit|[Ss]tudio|[Ff]lat)?"
street_type = (r"\d+[&-]*\w*\s*"
r"(?:[Ee]nd|[Gg]reen|[Cc]auseway|[Cc]heapside|[Cc]rescent|"
r"[Ss]treet|[Ll]ane|[Ww]alk|[Rr]oad|[Aa]venue|[Dd]rive|"
r"[Pp]ark|[Ww]ay|[Pp]lace|[Pp]arade|[Ii]ndustrial"
r"[Ee]state|[Tt]rading [Ee]state|[Hh]ouse|[Gg]reen)")
postcode = r"[A-Z0-9][A-Z0-9][A-Z0-9]?[A-Z0-9]? {1,2}[0-9][A-Z]{2}"
pattern = re.compile(rf"{building_type}{space}{street_type}(?:\s{{1,5}}\w+){{0,5}}"
rf"{space}{postcode}")
print(pattern.pattern)
try:
return [re.sub(r"\s+", r" ", x) for x in pattern.findall(string)]
except Exception as e:
return (f"Error looking for address, exception {e}")

print(parse_results('Unit 23 End AS4 0SS'))

关于python - 在 Python 中使用原子分组的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67175521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com