【问题标题】:Python using dictionary for multiple RegEX re.subPython对多个RegEX re.sub使用字典
【发布时间】:2019-02-16 20:49:49
【问题描述】:

我正在尝试使用 Python 3 处理来自 SNMP sysDescr.0 输出的文本,我需要使用包含以下模式及其替换的字典:

myDict = {
    r' \(\/sw.+': '',
    r' \(\/ws.+$': '',
    r'Compiled on.{36}': '',
    r'Ruckus Wireless, Inc. ': '',
    r'Brocade Communications Systems, Inc. ': '',
    r' Switch': '',
    r', ROM': ' - ROM',
    r' revision': 'revision',
    r' IronWare': 'IronWare'
}

我在这里找到了下面的代码,但是字典中的前三个模式不起作用,其余的都可以,我不知道为什么:

def multiple_replace(myDict, text):
    regex = re.compile(r'(%s)' % '|'.join(map(re.escape, myDict.keys())))
    return regex.sub(lambda mo: myDict.get(mo.group(), mo.group()),text)

如何修改上述函数才能正确运行前三种模式的 RegEX?我在这里尝试了大多数类似的解决方案,但没有一个能够处理前三种模式。

我的简单版本如下,但我真的很想看看应该如何修改第一个解决方案以使其正常工作,因为我还是 python 新手:

def multiple_replace(myDict, text):
    for key, val in myDict.items():
        if re.search(key, text):
            text = re.sub(key, val, text)
    return text  

这是一个输出示例:

HP J9856A 2530-24G-2SFP+ Switch, revision YA.16.05.0004, ROM YA.15.20 (/ws/swbuildm/rel_venice_qaoff/code/build/lakes(swbuildm_rel_venice_qaoff_rel_venice)) (Formerly ProCurve),.1.3.6.1.4.1.11.2.3.7.11.166
ProCurve J9088A Switch 2610-48, revision R.11.122, ROM R.10.06 (/sw/code/build/nemo),.1.3.6.1.4.1.11.2.3.7.11.77
Ruckus Wireless, Inc. ICX7250-48-HPOE, IronWare Version 08.0.70aT211 Compiled on Jan 18 2018 at 04:21:25 labeled as SPS08070a,.1.3.6.1.4.1.1991.1.3.62.2.2.1.1

我需要它变成什么:

HP J9856A 2530-24G-2SFP+,revision YA.16.05.0004 - ROM YA.15.20,.1.3.6.1.4.1.11.2.3.7.11.166
HP J9088A 2610-48,revision R.11.122 - ROM R.10.06,.1.3.6.1.4.1.11.2.3.7.11.77
ICX7250-48-HPOE,IronWare Version 08.0.70aT211 SPS08070a,.1.3.6.1.4.1.1991.1.3.62.2.2.1.1

老实说,我不知道哪个更好或更快,感谢您的意见。

谢谢

【问题讨论】:

  • 您正在混合正则表达式和文字模式。 map(re.escape, myDict.keys()) 转义字符串,并破坏正则表达式模式。
  • 谢谢,那函数应该怎么变成呢?我应该删除 re.escape 吗?
  • 不,请确保您的密钥都是正则表达式。但是,看起来您的第一个正则表达式并没有按照您的预期执行。您必须尝试r' \(\/sw.+\)'r' \(\/ws.+\)'。见ideone.com/iXaHBt
  • 非常感谢,但我没有使用第二种解决方案。另请注意,它需要修改如下: def multiple_replaec(mydict, text): for rx, repl in mydict.items(): if re.search(rx, text): text = re.sub(rx, repl, text) 返回 text.strip()
  • 顺便说一句,在函数中添加 re.search 可以加快执行速度。

标签: regex python-3.x replace


【解决方案1】:

你应该确保你的键都是编译的re对象,一旦你准备好你的正则表达式替换字典,你将需要遍历这些键值对并一个一个地执行替换,使用

for rx,repl in myDict.items():
        text = rx.sub(repl, text)

其中rx 将是编译后的re 对象,repl 是替换字符串。

完整代码sn-p:

import re
myDict = {
    re.compile(r' \(\/sw.+\)'): '',
    re.compile(r' \(\/ws.+\)'): '',
    re.compile(r'Compiled on.{36}'): '',
    re.compile(re.escape(r'Ruckus Wireless, Inc. ')): '',
    re.compile(re.escape(r'Brocade Communications Systems, Inc. ')): '',
    re.compile(re.escape(r' Switch')): '',
    re.compile(re.escape(r', ROM')): ' - ROM',
    re.compile(re.escape(r' revision')): 'revision',
    re.compile(re.escape(r' IronWare')): 'IronWare'
}
s = """HP J9856A 2530-24G-2SFP+ Switch, revision YA.16.05.0004, ROM YA.15.20 (/ws/swbuildm/rel_venice_qaoff/code/build/lakes(swbuildm_rel_venice_qaoff_rel_venice)) (Formerly ProCurve),.1.3.6.1.4.1.11.2.3.7.11.166
ProCurve J9088A Switch 2610-48, revision R.11.122, ROM R.10.06 (/sw/code/build/nemo),.1.3.6.1.4.1.11.2.3.7.11.77
Ruckus Wireless, Inc. ICX7250-48-HPOE, IronWare Version 08.0.70aT211 Compiled on Jan 18 2018 at 04:21:25 labeled as SPS08070a,.1.3.6.1.4.1.1991.1.3.62.2.2.1.1"""

def multiple_replace(myDict, text):
    for rx,repl in myDict.items():
        text = rx.sub(repl, text)
    return text

print(multiple_replace(myDict, s))

请参阅Python demo

输出:

HP J9856A 2530-24G-2SFP+,revision YA.16.05.0004 - ROM YA.15.20,.1.3.6.1.4.1.11.2.3.7.11.166
ProCurve J9088A 2610-48,revision R.11.122 - ROM R.10.06,.1.3.6.1.4.1.11.2.3.7.11.77
ICX7250-48-HPOE,IronWare Version 08.0.70aT211 SPS08070a,.1.3.6.1.4.1.1991.1.3.62.2.2.1.1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 2013-10-05
    • 2015-05-24
    • 2020-06-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多