我正在为一种提供相同"三重引语的小语言编写解析器"字符串作为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)
所以我想我需要一些东西。任何想法都会受到热烈欢迎......
答案 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', '"""')
希望将来会帮助某人......