python正则表达式忽略文本
我的代码中有一个缺陷列表: 该列表包含一个过程的名称、它的参数和一个我必须更改的参数,并在前面添加“CONST” 我想找到所有符合模式的程序 程序名称(参数列表和各处注释) i、 e。 代码程序测试中的缺陷(X:字符串;Y:字符串);(Y需要常数) 我想知道程序 过程测试(X:STRING;{SOME COMMENTS HERE}Y:STRING{SOME MORE COMMENTS HERE}) 然后在Y:STRING之前添加单词CONST,以最终获得python正则表达式忽略文本,python,regex,Python,Regex,我的代码中有一个缺陷列表: 该列表包含一个过程的名称、它的参数和一个我必须更改的参数,并在前面添加“CONST” 我想找到所有符合模式的程序 程序名称(参数列表和各处注释) i、 e。 代码程序测试中的缺陷(X:字符串;Y:字符串);(Y需要常数) 我想知道程序 过程测试(X:STRING;{SOME COMMENTS HERE}Y:STRING{SOME MORE COMMENTS HERE}) 然后在Y:STRING之前添加单词CONST,以最终获得 PROCEDURE TEST (X :
PROCEDURE TEST (X : STRING; {SOME COMMENTS HERE} CONST Y: STRING {SOME COMMENTS HERE});
考虑到我们可以在nplaces中多次重复{这里有一些注释},在最终版本中,我希望保留这些注释
我知道还有其他的可能性,但我想用正则表达式
可能吗?可能是这样的吧
import re
with open('lines', 'r') as input:
for line in input:
match = re.search('PROCEDURE TEST \(X : STRING;\s*(\{.*\})*\s*Y: STRING\);', line)
if match:
print 'PROCEDURE TEST (X : STRING;', match.group(1), 'CONST Y: STRING);'
[编辑:好的,根据我对您的描述的理解,您有两个文件:一个包含同一行中每个建议更正的所有缺陷列表(这是我代码中的“缺陷”),另一个文件,您实际上希望在其中应用建议的修复(“代码”)
如果过程名称实际上是您想要匹配的参数,并且您给我们提供的示例是正确的(在变量声明之后和注释之前总是有一个“;”,除了最后一个变量,其中没有“;”),那么这段代码应该可以执行
如果要查看正在搜索的regexp,请取消对“print”行的注释
import re
with open('imperfections', 'r') as imp:
imperfections = imp.readlines()
with open('code', 'r') as cod:
code = cod.readlines()
for imp in imperfections:
parsed = re.search('(.*); \((\w+) NEEDS (\w+)', imp)
find = parsed.group(1).replace('(', '\(')
find = find.replace(')', '\s*(\{.*\})*\)')
find = find.replace(';', ';\s*(\{.*\})*')
replace = parsed.group(2)
replace_with = ' '.join([parsed.group(3), replace])
#print 'find: "%s" replace "%s" with "%s"' % (find, replace, replace_with)
for line in code:
match = re.search(find, line)
if match:
print re.sub(replace, replace_with, line)[:-1]
[第二次编辑-我忘了你想保留注释:]要忽略大括号之间的任何内容,你可以创建一个临时字符串,删除大括号之间的文本并与之匹配。然后,使用difflib
合并这两个字符串。
这是您的一个示例,将其更改为在所有行上进行迭代
import re
import difflib
def merge(string1, string2):
diffs = difflib.SequenceMatcher(None, string2, string1).get_opcodes()
result = ''
last_index = 0
for diff in [x for x in diffs if x[0] in ['insert', 'replace']]:
if diff[0] == 'replace':
result += string2[last_index:diff[1]] + string1[diff[3]:diff[4]] + string2[diff[1]:diff[2]]
else:
result += string2[last_index:diff[1]] + string1[diff[3]:diff[4]]
last_index = diff[2]
result += string2[last_index:]
return result
original = "PROCEDURE TEST (X: STRING; {Hi, I'm a comment} Y: INT {me too!})"
stripped = re.sub(r'\s*\{[^}]*\}\s*', '', original)
if re.search('PROCEDURE TEST \(X: STRING;Y: INT\)', stripped):
correct = stripped.replace('Y', 'CONST Y')
print merge(original, correct)
为什么不像下面这样简单
result = re.sub("Y:", "CONST Y:", subject)
如果太简单,请告诉我们。也许您希望所有第二个参数都接收一个常量,而不考虑名称(在本例中为Y)?是的,这是可能的。你试过写一个正则表达式来做你想做的吗?是否允许“这里的一些注释”包含
{
和}
?如果是这样的话,那么你希望他们“配对”吗?如果是这样,那么这在regexp中是不可能的。如果不允许(例如,如果}
不允许出现在注释中),那么应该是可能的。对不起,我想清楚地解释我的问题,我在问题中添加了更多信息几乎在那里,你可以在过程声明中的任何变量之间添加注释,我想用某种方式忽略所有注释(介于{}之间的任何内容)我忘了说“procedure test”和const y:string之后的what是变量,我想用替换来处理任何过程声明,这就是为什么在问题中我问如何忽略文本,所以每个“procedure”都有2个参数?线条是否遵循这种模式“[大写字符和空格]([单个大写字符]:[大写字符];[{optional comment}][single uppercase char]:[uppercase chars][{optional comment}]);”
要回答编辑,我的第一个文件中的所有行都包含行号和需要以“const”作为前缀的变量名,在我的源代码文件的行号处,我找到了一个带有变量列表的过程声明,在多行之后(我不知道确切位置),我找到了该过程的实现,同样使用相同的参数,但参数之间可能有注释,这就是为什么我“简单地”想要找到我的过程声明的匹配项(每个参数之间有大量的\s*),忽略注释partwell,我想说我的示例与您想要做的非常接近。。你应该能够调整代码以适应你的实际问题;如果你不首先准确地说明你的问题是什么,那么试图想出一个对你有好处的解决方案是没有意义的..我想我可以解释得更多,我的文件包含几个过程Delcaration,很多都有y:string,我只需要根据参数listok修改其中一个过程,放大其中一个过程的标准是什么?这听起来是构建RegExt的关键。参数列表和过程的名称定义了一个过程:带注释的过程,带注释的过程(介于{}之间的任何内容),它与我想在stackoverflow找到的过程相匹配,以编辑原始问题供参考