Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python正则表达式以单引号匹配文本,忽略转义引号(和制表符/换行符)_Python_Regex - Fatal编程技术网

Python正则表达式以单引号匹配文本,忽略转义引号(和制表符/换行符)

Python正则表达式以单引号匹配文本,忽略转义引号(和制表符/换行符),python,regex,Python,Regex,给定一个文本文件,其中我要匹配的字符由单引号分隔,但可能有零个或一个转义单引号,以及零个或多个制表符和换行符(非转义)-我只想匹配文本。例如: 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\'

给定一个文本文件,其中我要匹配的字符由单引号分隔,但可能有零个或一个转义单引号,以及零个或多个制表符和换行符(非转义)-我只想匹配文本。例如:

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.
我已经设法创建了一个几乎可以做到这一点的正则表达式-它处理转义引号,但不处理换行符:

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,我不在乎它是否分布在多个组中,很容易重新组合它们

一些答案说,只需使用解析文本的代码即可。虽然我确信我可以做到这一点,但我已经非常接近拥有一个可以工作的正则表达式了:),而且它似乎应该是可行的

更新:我刚刚意识到我正在使用Python readlines()来获取每一行,这显然是在分解传递给正则表达式的行。我正在考虑重新编写,但关于这一部分的任何建议都将非常有用。

这应该可以做到:

menu_item = '((?:[^'\\]|\\')*)'

这里的
(?:[^'\]\\\\\')*
部分匹配任何字符的任何序列,除了
'
\
或文字
\'
。前一个表达式
[^'\\]
也允许使用换行符和制表符,然后需要用单个空格替换这些换行符和制表符。

您可以这样冷试:

pattern = re.compile(r"menu_item = '(.*?)(?<!\\)'", re.DOTALL)

pattern=re.compile(r“menu_item=”(.*)(此测试脚本应能完成以下功能:

重新导入
re_sq_long=r”“”
#将单引号字符串与转义内容匹配。
""开篇文字引述
(#$1:捕获字符串内容
[^'\]*#零或更多非-',非反斜杠
(?:#“展开循环”!
\\.#什么都允许。
[^'\]*#零或更多非-',非反斜杠
)*#完成{(特殊正规*)*}构造。
)#End$1:字符串内容。
“#结束文字引用
"""
re_sq_short=r“([^'\\]*(?:\\.[^'\]*)*)”
数据=r''
菜单项=‘砂锅菜’;
菜单项='肉
面包;
菜单项=‘托尼的魔法披萨’;
菜单项=‘汉堡包’;
菜单项=‘戴夫著名的比萨饼’;
菜单项=‘Dave’鲜为人知
陀螺';'''
matches=re.findall(re_sq_long,data,re.DOTALL | re.VERBOSE)
菜单项=[]
对于匹配中的匹配:
match=re.sub('\s+','',match)#清除空白
match=re.sub(r'\\','',match)#删除转义符
菜单项。附加(匹配)#添加到菜单列表
打印(菜单项)
以下是正则表达式的简短版本:

([^'\]*(?:\\.[^'\]*)*)”

此正则表达式使用Jeffrey Friedl的“展开循环”效率技术进行了优化。(请参阅:)以了解详细信息

请注意,上面的正则表达式相当于下面的正则表达式(这更常见,但在大多数NFA正则表达式实现中要慢得多):


'(((?:[^'\]\124\\)*)

当你说“替换为一个空格”-你的意思是在运行此RE之前清理/删除制表符/换行符吗?当我尝试您的RE时,它没有任何一行与换行符匹配。@John C:不,我会在之后使用类似于
RE.sub(r“[\n\r\t]+”,“,match)的东西来完成此操作
。但是,对于有换行符的输入行,我的匹配变量m是空的,因此没有任何东西可以替代。Arg!查看我的代码,我正在对输入文件执行readlines(),我认为这在换行符上是中断的。显然,我需要重新编写更多代码(叹气)。值得注意的是,虽然此表达式适用于转义引号,但当它遇到另一个转义序列(如
\n
或一个单独的反斜杠)时,它也将不起作用。您需要将预期遇到的所有转义序列添加到组中,即:
(?:[^'\\]\\\\\\\\\\\\\\\\r \\\\\\\\n\\\\\\\\\\\\\\\ \*)“
看起来很有趣,但正如我在另一条评论中指出的,我刚刚意识到我正在做一个readlines(),它在换行时中断,因此我还有另一个问题要解决。可能重复的不是重复的-我正在尝试处理(非转义)换行符也会打断我的输入数据。我同意,但我认为无论如何都值得指出。只需使用
re.MULTILINE
()匹配多行,
$
忽略/匹配尾行,
\s
(同一链接)匹配新闻空间。继续,grasshopper;)附带说明:string
菜单项='Dave's less-known\n gyro';
不包含转义单引号。string-literal包含一个转义单引号,但这有助于Python将其与string-literal引号的结尾区分开来。如果您希望实际测试用例包含转义单引号,则需要类似于
ohai='Dave\\\\\'s'