给定一个文本文件,其中要匹配的字符由单引号分隔,但可能有零个或一个转义单引号,以及零个或多个制表符和换行符(未转义)-我只想匹配文本。示例:
menu_item = 'casserole';
menu_item = 'meat
loaf';
menu_item = 'Tony\'s magic pizza';
menu_item = 'hamburger';
menu_item = 'Dave\'s famous pizza';
menu_item = 'Dave\'s lesser-known
gyro';
我只想抓取文本(和空格),忽略制表符/换行符-实际上我并不关心转义引号是否出现在结果中,只要它不影响匹配:
casserole
meat loaf
Tonys magic pizza
hamburger
Daves famous pizza
Dave\'s lesser-known gyro # quote is okay if necessary.
我已经创建了一个regex,几乎会这样做-它处理转义引号,但不处理换行符:
menuPat = r"menu_item = \'(.*)(\\\')?(\t|\n)*(.*)\'"
for line in inFP.readlines():
m = re.search(menuPat, line)
if m is not None:
print m.group()
这里肯定有很多正则表达式问题——但大多数都在使用Perl,如果有一个问题能满足我的要求,我就想不出来了:)而且由于我使用的是Python,我不在乎它是否分布在多个组中,所以很容易重新组合它们。
有人说,一些答案只是与代码解析文本。虽然我确信我可以做到这一点-我非常接近拥有一个工作的regex:)而且似乎它应该是可行的。
更新:我刚刚意识到我正在使用Pythonreadlines()来获取每一行,这显然是在分解传递给regex的行。我正在考虑重新编写它,但任何关于这方面的建议也会非常有帮助。
这应该做到:
这里的
(?:[^'\\]|\\')*
部分匹配任何字符序列,除了'
和\
或文本\'
。前一个表达式[^'\\]
也允许换行符和制表符,然后需要用单个空格替换它们。这个经过测试的脚本应该可以做到:
下面是regex的简短版本:
'([^'\\]*(?:\\.[^'\\]*)*)'
这个regex使用Jeffrey Friedl的“展开循环”效率技术进行优化。(参见:Mastering Regular Expressions (3rd Edition))了解详细信息。
注意,上面的regex相当于下面的regex(这在大多数NFA regex实现中更常见,但速度慢得多):
'((?:[^'\\]|\\.)*)'
你可以这样试试:
它将在找到的第一个单引号处开始匹配,并在没有反斜杠的第一个单引号处结束。它还捕获在两个单引号之间找到的任何换行符和制表符。
相关问题 更多 >
编程相关推荐