【问题标题】:Parsing with Regex on badly formatted string使用正则表达式解析格式错误的字符串
【发布时间】:2021-07-18 13:53:32
【问题描述】:

我正在用 Python 解析一个巨大的文件,其中包含以下行:

"Value names: 0 = Something, 1 = Something, else, 4 = A value, 5 = BAD - enough, 6 GOOD, 7 = Ugly,"

我的目标是将它们放入字典中。

问题在于它们的书写方式根本不一致,其中一些缺少逗号、等号等。而且名称中可能还有逗号和其他东西。数字(键)也可能包含多个数字。我唯一确定的是,名字中没有数字。

正因为如此,我想尝试一下正则表达式,但结果比预期的要困难一些。

我试过的是这个。

s = "Value names:  0 = Something, 1 = Something, else, 4 = A value 5 = BAD, 6 GOOD, 7 = Ugly,"
pattern = re.compile(r'([0-9]+)([A-Z]+)')

for (numbers, letters) in re.findall(pattern, s):
    ...

但是,这(对于受过训练的眼睛来说可能很明显)不起作用。

由于我对正则表达式不是很精通,因此我非常感谢一些帮助,因为我无法直接编辑文件,而且所有手动解析技巧似乎都不足。

【问题讨论】:

    标签: python regex text-parsing re


    【解决方案1】:

    你可以使用

    (?P<keys>\d+)\s*(?:=\s*)?(?P<values>.*?)(?=\s*(?:,\s*)?(?:\d|\Z))
    

    请参阅regex demo详情

    • (?P&lt;keys&gt;\d+) - 组“键”:一位或多位数字
    • \s* - 零个或多个空格
    • (?:=\s*)? - = 和零个或多个空格的可选序列
    • (?P&lt;values&gt;.*?) - 组“值”:除换行符之外的任何零个或多个字符,尽可能少
    • (?=\s*(?:,\s*)?(?:\d|\Z)) - 在当前位置的右边,必须有
      • \s* - 零个或多个空格
      • (?:,\s*)? - , 和零个或多个空格的可选序列
      • (?:\d|\Z) - 数字或字符串结尾。

    Python demo

    import re
    text = "Value names:  0 = Something, 1 = Something, else, 4 = A value, 5 = BAD - enough, 6 GOOD, 7 = Ugly,"
    pattern = r"(?P<keys>\d+)\s*(?:=\s*)?(?P<values>.*?)(?=\s*(?:,\s*)?(?:\d|\Z))"
    for match in re.finditer(pattern, text):
        print(match.groupdict())
    

    输出:

    {'keys': '0', 'values': 'Something'}
    {'keys': '1', 'values': 'Something, else'}
    {'keys': '4', 'values': 'A value'}
    {'keys': '5', 'values': 'BAD - enough'}
    {'keys': '6', 'values': 'GOOD'}
    {'keys': '7', 'values': 'Ugly'}
    

    【讨论】:

    • 非常感谢。原来名称中也有整数,所以我不得不将正则表达式更改为(?P&lt;keys&gt;\d+)\s*(?:=\s*)(?P&lt;values&gt;.*?)(?=\s*(?:,\s*)?(?:\d*\s*?=|\Z)),并依靠= 来分隔。但是因为你的回答很详细,所以没问题。顺便说一句,非常感谢 regex101.com 链接。令人难以置信的工具!
    猜你喜欢
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-10
    • 2010-11-22
    相关资源
    最近更新 更多