0

目前我下面的正则表达式也在评论中匹配评论,例如对于下面的输入,它同时匹配 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
4

1 回答 1

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 个或多个不是斜线的字符(非贪婪)/或者它们是斜线但前提是前面没有a *。在字符串的另一端,我们对/*模式执行相同的操作;允许使用斜杠,但前提是后面没有*.

不再需要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
于 2013-01-10T08:43:32.033 回答