python正则表达式忽略文本

时间:2012-03-22 13:20:08

标签: python regex

我的代码中有一些不完美的列表: 列表包含一个过程的名称,它的参数和我必须更改的一个参数,在它前面添加'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},在最终版本中我想保留评论

我知道还有其他可能性,但我想用正则表达式做到这一点 有可能吗?

2 个答案:

答案 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)?