我的代码中有一些不完美的列表: 列表包含一个过程的名称,它的参数和我必须更改的一个参数,在它前面添加'CONST'
我想找到与模式匹配的所有程序 程序的名称(参数列表以及遍布各处的评论)
即。 代码中的不完美程序测试(X:STRING; Y:STRING); (Y NEEDS CONST)
我想找到这个程序 程序测试(X:STRING; {这里的一些评论} Y:STRING {此处有一些评论}};
然后在Y:STRING之前添加单词CONST以最终获得
PROCEDURE TEST (X : STRING; {SOME COMMENTS HERE} CONST Y: STRING {SOME COMMENTS HERE});
考虑到我们可以在nplaces中重复使用{SOME COMMENTS HERE},在最终版本中我想保留评论
我知道还有其他可能性,但我想用正则表达式做到这一点 有可能吗?
答案 0 :(得分:0)
或许这样的事情?
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);'
[编辑:] 好的,所以我从您的描述中了解到您有两个文件:包含同一行中每个建议更正的所有缺陷列表(这是我的代码中的'不完美')和另一个您真正想要应用建议修复('代码')的文件。
如果程序名称实际上是您想要匹配的参数,并且您给我们的示例是正确的(您在变量声明之后和评论之前总是有';'除了最后一个变量,你没有';')这段代码应该这样做。
如果要查看正在搜索的正则表达式,请取消注释“打印”行。
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)
答案 1 :(得分:0)
为什么不能像以下那样简单?
result = re.sub("Y:", "CONST Y:", subject)
如果太简单,请告诉我们。也许你想要所有第二个参数都接收一个CONST而不管名字(在这种情况下为Y)?