![](/img/trans.png)
[英]Why does my regular expression return tuples for every character in a string?
[英]Why does this python regular expression return the wrong string
下面我有一段代碼應將一個字符串替換為另一個字符串,但似乎不這樣做。 我不是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字符串,計算值,然后將一個字符串放在原始字符串中。 我一直在嘗試很多東西,但似乎沒有任何效果。
這不是您的問題,但是以下3行令人驚嘆:
final = hex(CalcCRC( str_to_crc ))[:2]
value = '%08X' % CalcCRC( str_to_crc )
final = final + value.upper()
假設CalcCRC返回一個非負整數(例如12345567890
第一行將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)
環割城市的更多內容
這些行:
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'“((ww +)”',crc).group(1)
快速瀏覽一下真正的答案:
您(除其他外)需要使用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'
這是你想要的嗎? :
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()
,它非常重要,否則,如果重寫的內容比初始內容短,它仍然是一條尾巴。
。
約翰·馬欽(John Machin)
沒有錯誤,我上面的解決方案是正確的,它給出了
printf( "0x%08X\n", _CalcCRC("THIS_IS_A_CRC"), 0x97DFEAC9 );
printf( "0x%08X\n", _CalcCRC("PATIENT_ZERO"), 0x0D691C21 );
自您發表評論以來,我沒有更改過它。 我認為我首先發布了一個不正確的解決方案(因為我執行了各種測試來驗證某些行為,並且,我有時會混淆我的文件和代碼),然后您復制了此錯誤的代碼進行嘗試,然后我意識到有一個錯誤並更正了代碼,然后您在未注意到我已更正的情況下發布了評論。 我想沒有其他原因會造成這種混亂。
順便說一句,要獲得相同的結果,在定義regx的模式中甚至不需要兩組,一個組就足夠了。 以下這些regx
和ripl()
工作:
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 0x97DFEAC9
, if x=="PATIENT_ZERO": return 0x0D691C21
; 我通過查看Joe在他的問題中期望的結果來挑選出這些關聯。
現在,關於您對我的“關於功能的重新定義的觀點完全是胡說八道”的肯定,我認為我的意思還不夠。 把正則表達式至REGx和功能RIPL()的默認參數的功能ReplaceCRC()的參數有一個結果:對象至REGx和RIPL()只創建一次,此刻功能ReplaceCRC的定義()是被執行。 因此,如果在執行過程中多次應用ReplaceCRC() ,則不會重新創建這些對象。 我不知道在Joe的程序執行過程中是否多次調用過ReplaceCRC()函數,但是我認為,最好將此功能放在代碼中,以防可能有用。 也許,我應該在答案中強調這一點,而不要添加注釋以使我的代碼相對於您的代碼合理。 但是我試圖限制我有時寫答案的時間太長。
這些解釋是否澄清了這些要點,並減輕了您的煩惱?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.