我可以显示Python正则表达式匹配的位置吗?

时间:2013-09-13 08:54:33

标签: python regex

所以我有一个很长的输入字符串,我从一个正则表达式中提取了几位数据。输入由客户端提供,他们经常忘记重要的部分,这些部分不仅是正则表达式匹配所必需的(它们是),但它们是这个正则表达式构建的数据库的组成部分。

我希望能够在输入中指出 where 匹配开始失败,为什么(向他们展示正则表达式接下来会发生什么)。< / p>

性能是一个问题。正则表达式包含几个字段,因此将其分成几个单独的正则表达式匹配可能会令人望而却步。

以下是真实内容的简化版本:

^(?:(?P<doors>\d) Doors).*(?P<transmission>Automatic|Manual)

一些样本输入(和所需的输出):

"3 Doors blah blah blah Manual"  # match!
"Guadeloupe blah blah blah Sneezes"  # Reply: Missing doors
"2 Doors blah blah blah Psychic" # Reply: Missing transmission 

2 个答案:

答案 0 :(得分:2)

您的问题太广泛,无法由Python Regex Engine处理。你需要一个有限的自动机引擎(更具体的NFA),编写你自己的解析器并提供字符串,看看它失败的原因和原因。

或者,您可以使用PyParsing,创建一个语法(您可以在PyParsing Wiki中找到的示例)http://pyparsing.wikispaces.com/file/view/dfmparse.py之类的内容 。如果你是PyParsing的新手,会有一个陡峭的学习曲线,但是一旦你掌握了这个概念,实现你想要的就是散步。

答案 1 :(得分:1)

编写解析器的想法(自我的JavaCC时代以来至少已经过了10年)让我觉得有点恼火,而且我没有比它只是运行一堆编译的REGEX更快出售...但是,我想我已经提出了一个合适的解决方法。

我们首先使用单个正则表达式而如果失败,我们会使用增量式正则表达式。如果失败率低,这根本不是性能问题。

REGEXES = [
    (r'(?:(?P<doors>\d) Doors)', 'doors'),
    (r'.*(?P<transmission>Automatic|Manual)', 'transmission'),
]
FAILS = [(re.compile('^' + r[0], re.IGNORECASE), r[1]) for r in REGEXES]
MATCHER = re.compile('^' + ''.join([r[0] for r in REGEXES]), re.IGNORECASE)


# ... later ...

m = MATCHER.match(input)

if not m:
    working = input
    for r in FAILS:
        s = r[0].split(input)
        if len(s) > 1:
            working = s[-1]  # we use last group in the split
            continue
        # we have a problem here!!
        # we know the group (the regex and the label we gave it)
        # we can show the user what we're trying to match and against what
        return blah

# otherwise we can start working with m's groups.