0

下面我有一段代码应该用另一个字符串替换一个字符串,但似乎没有这样做。我不是 python 或正则表达式专家,谁能告诉我为什么这可能会出错。

def ReplaceCRC( file_path ):
    file = open(file_path,'r+');
    file_str = file.read()
    if( file_str <> '' ):
         crc_list        = re.findall(r'_CalcCRC[(]\s*"\w+"\s*[)]', file_str);
         strs_to_crc     = []
         new_crc_list    = []
         if( crc_list ):
              for crc in crc_list:
                   quote_to_crc    = re.search(r'"\w+"', crc);
                   str_to_crc      = re.search(r'\w+', quote_to_crc.group() ).group();
                   final           = hex(CalcCRC( str_to_crc ))[:2]
                   value           = '%08X' % CalcCRC( str_to_crc )
                   final           = final + value.upper()
                   final_crc       = Insert( crc, ', ' + final + ' ', -1)
                   new_crc_list.append( final_crc )
              if( new_crc_list <> [] ):
                   for i in range(len(crc_list)):
                       print crc_list[i]
                       print new_crc_list[i]
                       term = re.compile( crc_list[i] );
                       print term.sub( new_crc_list[i], file_str );

这是它正在操作的文件:

printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC") );
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO") );

这是输出

_CalcCRC("THIS_IS_A_CRC")
_CalcCRC("THIS_IS_A_CRC", 0x97DFEAC9 )
printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC") );
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO") );

_CalcCRC("PATIENT_ZERO")
_CalcCRC("PATIENT_ZERO", 0x0D691C21 )
printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC") );
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO") );

它应该做的是找到 CRC 字符串,计算值,然后将一个字符串放在原始字符串中的位置。我一直在尝试一堆东西,但似乎没有任何效果。

4

3 回答 3

1

不是你的问题,但是这 3 行是惊人的:

final           = hex(CalcCRC( str_to_crc ))[:2]
value           = '%08X' % CalcCRC( str_to_crc )
final           = final + value.upper()

假设 CalcCRC 返回一个非负整数(例如 12345567890

无论输入如何,第1 行都设置final为“0x”!

>>> hex(1234567890)
'0x499602d2'
>>> hex(1234567890)[:2]
'0x'

第 2 行重复调用 CalcCRC!

>>> value           = '%08X' % 1234567890
>>> value
'499602D2'

注意已经value是大写了!

在第 3 行之后,final变为 '0x499602D2'

由于value不再使用,整个东西可以替换为

final = '0x%08X' % CalcCRC(str_to_crc)

更多来自 Circumlocution City

这些行:

quote_to_crc    = re.search(r'"\w+"', crc);
str_to_crc      = re.search(r'\w+', quote_to_crc.group() ).group();

可以替换为以下之一:

str_to_crc = re.search(r'"\w+"', crc).group()[1:-1] str_to_crc = re.search(r'"(\w+)"', crc).group(1)

于 2011-04-22T08:46:49.430 回答
0

这是你想要的吗?:

import re

def ripl(mat):
    return '%s, 0x%08X' % (mat.group(1),CalcCRC(mat.group(2)))

regx = re.compile(r'(_CalcCRC[(]\s*"(\w+)"\s*[)])')


def ReplaceCRC( file_path, regx = regx, ripl = ripl ):
    with open(file_path,'r+') as f:
        file_str = f.read()
        print file_str,'\n'
        if file_str:
             file_str = regx.sub(ripl,file_str)
             print file_str
             f.seek(0,0)
             f.write(file_str) 
             f.truncate()

编辑

指令忘记了f.truncate(),很重要,不然改写的内容比初始内容短的话还是个尾巴

.

编辑 2

约翰·马钦,

没有错,我上面的解决方案是对的,它给出了

printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC"), 0x97DFEAC9 ); 
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO"), 0x0D691C21 );

自从你发表评论以来,我没有改变它。我认为我首先发布了一个不正确的解决方案(因为我执行了一些不同的测试来验证某些行为,而且,你知道,我有时会混淆我的文件和代码),然后你复制了这个不正确的代码来尝试它,然后我意识到有一个错误并更正了代码,然后你发布了你的评论而没有注意到我已经更正了。我想没有其他原因会造成这种混乱。

顺便说一句,要获得相同的结果,在定义regx的模式中甚至不需要两组,一个就足够了。以下这些regxripl()可以正常工作:

regx = re.compile(r'_CalcCRC\(\s*"(\w+)"\s*\)')
# I prefer '\(' to '[(]', and same for '\)' instead of '[)]'

def ripl(mat):
    return '%s, 0x%08X' % (mat.group(),CalcCRC(mat.group(1)))

但不确定性仍然存在。我们的每一个结果都是明智的,相对于乔的不准确措辞。那么,他想要什么精确的结果呢?: 值0x97DFEAC9 必须插入到CalcCRC("THIS_IS_A_CRC")你的结果中,还是插入到我的结果CalcCRC("THIS_IS_A_CRC")中?

总而言之,我确实希望你获得一个可以运行的代码:我定义了一个我自己的函数CalcCRC(),简单地包含在if x=="THIS_IS_A_CRC": return 0x97DFEAC9and中if x=="PATIENT_ZERO": return 0x0D691C21;我通过看到乔在他的问题中暴露的结果来挑选出这些关联。

现在,关于你对我的“关于重新定义功能的观点完全是胡说八道”的令人讨厌的肯定,我认为我没有充分解释我的意思。将正则表达式regx和函数ripl()作为函数ReplaceCRC ()的参数的默认参数有一个结果:对象regxripl()只创建一次,此时函数ReplaceCRC()的定义是执行。因此,如果在执行中多次应用ReplaceCRC(),则不会重新创建这些对象。我不知道函数ReplaceCRC()在 Joe 的程序执行期间确实被调用了几次,但我认为将此功能放在代码中以防万一它可能有用是一个很好的做法。也许,我应该在我的回答中强调这一点,而不是评论来证明我的代码相对于你的代码是合理的。但我试图限制我有时写太多答案的倾向。

这些解释是否阐明了要点并缓解了您的烦恼?

于 2011-04-22T11:27:10.593 回答
0

快速浏览一下真正的答案:

您需要(除其他外)使用 re.escape() ....

term = re.compile(re.escape(crc_list[i]))

和你最后的压痕if看起来塞满了。

...晚餐后更多:-)

餐后更新

您对整个文件进行 3 次传递,而只有一次可以完成任务。除了消除大量混乱之外,主要的创新是使用re.sub允许替换成为函数而不是字符串的功能。

import re
import zlib

def CalcCRC(s):
    # This is an example. It doesn't produce the same CRC as your examples do.
    return zlib.crc32(s) & 0xffffffff

def repl_func(mobj):
    str_to_crc = mobj.group(2)
    print "str_to_crc:", repr(str_to_crc)
    crc = CalcCRC(str_to_crc)
    # If my guess about Insert(s1, s2, n) was wrong,
    # adjust the ollowing statement.
    return '%s"%s", 0x%08X%s' % (mobj.group(1), mobj.group(2), crc, mobj.group(3))

def ReplaceCRC(file_handle):
    regex = re.compile(r'(_CalcCRC[(]\s*)"(\w+)"(\s*[)])')
    for line in file_handle:
        print "line:", repr(line)
        line2 = regex.sub(repl_func, line)
        print "line2:", repr(line2)
    return

if __name__ == "__main__":
    import sys, cStringIO
    args = sys.argv[1:]
    if args:
        f = open(args[0], 'r')
    else:
        f = cStringIO.StringIO(r"""
printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC") )
other_stuff()
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO") )
""")
    ReplaceCRC(f)

不带参数运行脚本的结果:

line: '\n'
line2: '\n'
line: 'printf( "0x%08X\\n", _CalcCRC("THIS_IS_A_CRC") )\n'
str_to_crc: 'THIS_IS_A_CRC'
line2: 'printf( "0x%08X\\n", _CalcCRC("THIS_IS_A_CRC", 0x98ABAC4B) )\n'
line: 'other_stuff()\n'
line2: 'other_stuff()\n'
line: 'printf( "0x%08X\\n", _CalcCRC("PATIENT_ZERO") )\n'
str_to_crc: 'PATIENT_ZERO'
line2: 'printf( "0x%08X\\n", _CalcCRC("PATIENT_ZERO", 0x76BCDA4E) )\n'
于 2011-04-22T09:18:23.127 回答