【问题标题】:Replace exact match word with specific string in python用python中的特定字符串替换完全匹配的单词
【发布时间】:2015-01-29 05:34:38
【问题描述】:

我对 Python 完全陌生,这是我第一个替换 word 的脚本。

我的文件test.c 包含以下两行

printf("\nReboot not supported.  Exiting instead.\n");
fprintf(stderr, "FATAL:  operation not supported!\n");

现在我想将printffprintf 分别替换为//printf//fprintf

这是我尝试过的

infile = open('path\to\input\test.c')
outfile = open('path\to\output\test.c', 'w')

replacements = {'printf':'//printf', 'fprintf':'//fprintf'}

for line in infile:
    for src, target in replacements.iteritems():
        line = line.replace(src, target)
    outfile.write(line)
infile.close()
outfile.close()

但是用这个我得到了

fprintf//f//printf 这是错误的。

对于解决方案,已查看此 answer 但无法将其放入我的脚本中。

有人知道我该如何解决吗?

【问题讨论】:

    标签: python


    【解决方案1】:

    基本上,您希望将 printf 转换为 //printf 并将 fprintf 转换为 //fprintf。如果是这种情况,那么这可能有效,请尝试一下。

      outfile = open("test.c", 'r')
      temp = outfile.read()
      temp = re.sub("printf", "//printf", temp)
      temp = re.sub("f//printf", "//fprintf", temp)
      outfile.close()
      outfile = open("test.c","w")
      outfile.write(temp)
      outfile.close()
    

    【讨论】:

      【解决方案2】:

      python 中的 dict 没有排序。所以你不能保证 printfprintf 在下面一行遍历 dict 时首先被拾取:

      for src, target in replacements.iteritems():
      

      在当前情况下,print 似乎首先被选中,这就是您面临问题的原因。为避免此问题,请使用orderdict 或保留replacements 的字典列表。

      【讨论】:

      • 如何使用OrderdictOrderedDict(sorted(replacements.items(), key=lambda t: t[0])) 尝试过,但未定义的 OrderedDict 出现错误。
      【解决方案3】:

      这就是它正在做的事情。字典没有排序(你可能认为它们是),所以 fprintf 替换实际上是第一个,然后它替换了它的 printf 部分。顺序:

      fprintf -> //fprintf -> //f//printf
      

      【讨论】:

      • 那我该如何避免呢?
      • 使用上面提到的 orderdict 将允许您使用符合输入键顺序的字典,或者您可以使用列表代替。应该能解决问题。
      • @Jayesh 为避免这种情况,您可以列出或用元组代替 dict [('printf','//printf'), ('fprintf','//fprintf')]
      • @dragon2fly 由replacements = [{'printf':'//printf', 'fprintf':'//fprintf'}] 尝试,但出现类似AttributeError: 'list' object has no attribute 'iteritems' 的错误。
      • 小心你的括号。大括号表示字典......你想要圆形的。
      【解决方案4】:
      (?=\bprintf\b|\bfprintf\b)
      

      使用来自 re 模块的re.sub。参见演示。

      https://regex101.com/r/pM9yO9/18

      import re
      p = re.compile(r'(?=\bprintf\b|\bfprintf\b)', re.IGNORECASE | re.MULTILINE)
      test_str = "printf(\"\nReboot not supported. Exiting instead.\n\");\nfprintf(stderr, \"FATAL: operation not supported!\n\");"
      subst = "//"
      
      result = re.sub(p, subst, test_str)
      

      逐行传递您的文件并将输出打印到不同的文件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-05-31
        • 2012-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多