如何使用正则表达式解析三引号字符串?

时间:2018-04-04 11:17:33

标签: python regex

我正在为一种提供相同"三重引语的小语言编写解析器"字符串作为Python。语言很简单,可以被有限状态机有效地解析,其中转换由一堆正则表达式触发。

一个强大的限制是解析器必须逐行工作,因此解析三重引用的多行字符串需要至少两个状态用于FSM(一个在"输入"三重引号字符串,以及“#34;离开"它”。

我认为一个简单的解决方案是为每一行定义三个正则表达式组:一个用于开放"""模式,一个用于字符串字符,一个用于结束"""模式。因此,通过测试这三组的空虚,很容易触发正确的过渡

不幸的是,我无法找到正确的正则表达式来处理所有情况。这是我的实验结果:

text = '"""\nabc\n"abc"\n"""abc"""\nabc"""\n"""a"b"c\n"""a"b"c"""'

regex1 = r'\s*("""|")?(.*)("""|")?\s*'
regex2 = r'\s*("""|")?(.*?)("""|")?\s*'

for line in text.split('\n'):
    match = re.match(regex1, line)
    print(line, '-->', match.groups() if match else False)

以及运行此代码时的结果:

""" --> ('"""', '', None)
abc --> (None, 'abc', None)
"abc" --> ('"', 'abc"', None)
"""abc""" --> ('"""', 'abc"""', None)
abc""" --> (None, 'abc"""', None)
"""a"b"c --> ('"""', 'a"b"c', None)
"""a"b"c""" --> ('"""', 'a"b"c"""', None)

中间群体(。*)过于贪婪,并且吃掉了#34;结束的分隔符。另一方面,当使用惰性表单(请参阅regex2)时,它与所有字符串都不匹配。

""" --> ('"""', '', None)
abc --> (None, '', None)
"abc" --> ('"', '', None)
"""abc""" --> ('"""', '', None)
abc""" --> (None, '', None)
"""a"b"c --> ('"""', '', None)
"""a"b"c""" --> ('"""', '', None)

所以我想我需要一些东西。任何想法都会受到热烈欢迎......

2 个答案:

答案 0 :(得分:0)

这可能对您有用

^(\"([^\"\n\\]|\\[abfnrtv?\"'\\0-7]|\\x[0-9a-fA-F])*\"|'([^'\n\\]|\\[abfnrtv?\"'\\0-7]|\\x[0-9a-fA-F])*'|\"\"\"((?!\"\"\")[^\\]|\\[abfnrtv?\"'\\0-7]|\\x[0-9a-fA-F])*\"\"\")$

这是我从项目中剪切粘贴的内容。在regex101.com上查看它的运行情况。

答案 1 :(得分:-1)

最后,我发现这是非常接近我的第一个猜解:简单地用惰性限定符(.*?) 环绕通过正则表达式^(开始的行)和$(行尾):

regex3 = r'^\s*("""|")?(.*?)("""|")?\s*$'

获得预期结果:

""" --> ('"""', '', None)
abc --> (None, 'abc', None)
"abc" --> ('"', 'abc', '"')
"""abc""" --> ('"""', 'abc', '"""')
abc""" --> (None, 'abc', '"""')
"""a"b"c --> ('"""', 'a"b"c', None)
"""a"b"c""" --> ('"""', 'a"b"c', '"""')

希望将来会帮助某人......