我正在尝试编写regex (在Python程序中),以匹配如下所示的字符串:
"""(book "Moby Dick" (MLA) #foo ?bar baz)
"""(book "Moby Dick" (MLA))
"""(book "Moby Dick")我的准则是:
(?P<indent>\s*)("""|\'\'\'|blockquote:)(\((?P<type>\w*)\s*(["\'](?P<citation>.+?)["\'])?\s*(\((?P<format>\w+?)\))?(?P<other>.+?)\))?预期的结果是:
indent [0-8] ` `
type [12-16] `book`
citation [18-27] `Moby Dick`
format [30-33] `MLA`
other [34-44] ` #foo ?bar baz`对于第一个版本的字符串,这就是我得到的。但是,对于字符串的较短版本,“其他”组捕获了文本的早期部分,因此对于我得到的第二个版本:
indent [0-8] ` `
type [12-16] `book`
citation [18-27] `Moby Dick`
other [29-33] `(MLA`第三,我得到的是:
indent [0-8] ` `
type [12-16] `book`
other [17-28] `"Moby Dick"`所以我的问题是,为什么“其他”模式在前面的模式之前被匹配,我怎样才能得到模式的“引文”和“格式”部分来匹配第二和第三种情况下的预期文本?
发布于 2015-12-17 16:48:09
您还需要使(?P<other>.+?)模式成为可选的,以获得所需的结果:
reg = r'(?P<indent>\s*)("""|\'\'\'|blockquote:)(\((?P<type>\w*)\s*(["\'](?P<citation>.+?)["\'])?\s*(\((?P<format>\w+?)\))?(?P<other>.+?)?\))?'由于它不是可选的,regex引擎至少需要一个字符才能成功匹配正则表达式。因为其他模式是.+,所以后面有一个结束括号。因此,最后两个字符串other被匹配,而不是citation和format。
>>> import re
>>>
>>> reg = re.compile(r'(?P<indent>\s*)("""|\'\'\'|blockquote:)(\((?P<type>\w*)\s*(["\'](?P<citation>.+?)["\'])?\s*(\((?P<format>\w+?)\))?(?P<other>.+?)?\))?')
>>>
>>>
>>> s2 = ' """(book "Moby Dick" (MLA))'
>>>
>>> m2 = reg.match(s2)
>>> m2.groupdict()
{'indent': ' ', 'citation': 'Moby Dick', 'type': 'book', 'other': None, 'format': 'MLA'}
>>>
>>> s3 = ' """(book "Moby Dick")'
>>> m3 = reg.match(s3)
>>>
>>> m3.groupdict()
{'indent': ' ', 'citation': 'Moby Dick', 'type': 'book', 'other': None, 'format': None}https://stackoverflow.com/questions/34339683
复制相似问题