python - 几个类似的正则表达式。更快的方法来做到这一点?

标签 python regex python-3.x performance

我有一组相当简单的要求。我有一个对象列表(长度为 200 万),每个对象都有 2 个需要正则表达式的属性(其他属性未更改)

ZERO ONE TWO ... TEN 的值需要更改为它们的数值:1 2 ... 10

例子:

ONE MAIN STREET -> 1 MAIN STREET
BONE ROAD -> BONE ROAD
BUILDING TWO, THREE MAIN ROAD -> BUILDING 2, 3 MAIN ROAD
ELEVEN MAIN ST -> ELEVEN MAIN STREET
ONE HUNDRED FUNTOWN -> 1 HUNDRED FUNTOWN

很明显,有些号码没有更改,有些号码收费很奇怪。 这完全符合预期

我可以让这一切与我下面的东西一起工作。我的问题是,有没有一种聪明的方法可以让这一切运行得更快?我想过制作一个字典列表,其中键是单词数字,值是数字,但我认为这对性能没有帮助。或者重新编译每个正则表达式并将它们传递给这个函数?有什么聪明的主意可以让这个运行得更快吗?

def update_word_to_numeric(entrylist):
    updated_entrylist = []
    for theentry in entrylist:
        theentry.addr_ln_1 = re.sub(r"\bZERO\b", "0", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bONE\b", "1", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bTWO\b", "2", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bTHREE\b", "3", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bFOUR\b", "4", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bFIVE\b", "5", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bSIX\b", "6", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bSEVEN\b", "7", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bEIGHT\b", "8", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bNINE\b", "9", theentry.addr_ln_1)
        theentry.addr_ln_1 = re.sub(r"\bTEN\b", "10", theentry.addr_ln_1)

        theentry.addr_ln_2 = re.sub(r"\bZERO\b", "0", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bONE\b", "1", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bTWO\b", "2", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bTHREE\b", "3", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bFOUR\b", "4", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bFIVE\b", "5", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bSIX\b", "6", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bSEVEN\b", "7", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bEIGHT\b", "8", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bNINE\b", "9", theentry.addr_ln_2)
        theentry.addr_ln_2 = re.sub(r"\bTEN\b", "10", theentry.addr_ln_2)
        updated_entrylist.append(theentry)
    return updated_entrylist

也许这是一个很好的方法。 “这已经足够好了”的评论对我来说也很好 :)

最佳答案

使用一个正则表达式比使用十个要快得多(我注意到速度提高了 3 倍):

def replace(match):
    return {
        "ZERO": "0",
        "ONE": "1",
        "TWO": "2",
        "THREE": "3",
        "FOUR": "4",
        "FIVE": "5",
        "SIX": "6",
        "SEVEN": "7",
        "EIGHT": "8",
        "NINE": "9",
        "TEN": "10",
    }[match.group(1)]

pattern = re.compile(r"\b(ZERO|ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN)\b")

def update_word_to_numeric(entrylist):
    updated_entrylist = []
    for theentry in entrylist:
        theentry.addr_ln_1 = pattern.sub(replace, theentry.addr_ln_1)
        theentry.addr_ln_2 = pattern.sub(replace, theentry.addr_ln_2)
        updated_entrylist.append(theentry)
    return updated_entrylist

我正在使用鲜为人知的功能将 re.sub 函数作为第二个参数:它将获取一个匹配对象并返回替换字符串。这样我们就可以查找替换字符串。

我还使用了 re.compile 来预编译正则表达式,这也改进了时间,但没有大的变化那么多。

关于python - 几个类似的正则表达式。更快的方法来做到这一点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50514971/

相关文章:

python - 解释区间 [0, 1] 中明显联系的舍入方向上的惊人奇偶性

python - 使用 CouchDB-Python 批量取消删除 CouchDB 文档

python - 基于规则的 ngram 映射

python - 如何使用类装饰器计算实例方法调用

python - 如何通过Tensorflow python导入多个图像

python-3.x - 无法通过 bash 脚本激活 virtualenv

python - 用python解析二进制格式

Python - 1 程序,在不同端口但同一主机上发送和接收,这可能吗?

regex - 是否可以只用一个正则表达式来解决这个问题?

python - Python 中的正则表达式 findall()