如何进行非贪婪的比赛

时间:2013-01-10 08:36:36

标签: python regex

目前我的正则表达式是在评论中匹配评论,例如对于下面的输入它匹配test1和test2 ....如何仅匹配test2?

import re
string="""
/*
 * devkit (c) 2012-2013, ARM-3.4. aLL DATA conf.
 *

 *
 */
/*
 * devkit (c) 2012, ARM-3.4. aLL DATA conf.
 *
 *
 */

#ifndef code_abc_WDI_H
#define code_abc_WDI_H
"""
text="devkit \(c\) 2012, ARM-3.4. aLL DATA conf"

pattern = re.compile(r'/\*.*?'+ re.escape(text) + '.*?\*/', re.DOTALL)
print re.sub(pattern, "", string)

输出: -

/*
 * devkit (c) 2012-2013, ARM-3.4. aLL DATA conf.
 *

 *
 */

#ifndef code_abc_WDI_H
#define code_abc_WDI_H

1 个答案:

答案 0 :(得分:2)

首先,您双重转义\(\)输入文字,因此您输入的内容不匹配:

>>> re.escape(text)
'devkit\\ \\\\\\(c\\\\\\)\\ 2012\\,\\ ARM\\-3\\.4\\.\\ aLL\\ DATA\\ conf'

text重新定义为:

text="devkit (c) 2012, ARM-3.4. aLL DATA conf"

您需要使用否定外观来匹配 /**/评论开始和结束字符的任何内容:

pattern = re.compile(r'/\*(?:[^/]|(?<!\*)/)*?' + re.escape(text) + r'(?:[^/]|/(?!\*))*?\*/')

因此,这将匹配/*后跟0个或更多字符(非贪婪) not /斜杠,它们是斜线,但前面只有*。在字符串的另一端,我们对/*模式执行相同的操作;允许斜线,但前提是*

不再需要re.DOTALL,因为我们不再使用.点运算符了。

然后这可以正常工作:

>>> text = "devkit (c) 2012, ARM-3.4. aLL DATA conf"
>>> pattern = re.compile(r'/\*(?:[^/]|(?<!\*)/)*?' + re.escape(text) + r'(?:[^/]|/(?!\*))*?\*/')
>>> pattern.sub("", string)
'/*\n * devkit (c) 2012-2013, ARM-3.4. aLL DATA conf.\n *\n\n *\n */\n\n\n#ifndef code_abc_WDI_H\n#define code_abc_WDI_H\n'
>>> print pattern.sub("", input)
/*
 * devkit (c) 2012-2013, ARM-3.4. aLL DATA conf.
 *

 *
 */


#ifndef code_abc_WDI_H
#define code_abc_WDI_H