[英]Python replace, using patterns in array
我需要使用數組替換字符串中的一些東西,它們看起來像這樣:
array = [3, "$x" , "$y", "$hi_buddy"]
#the first number is number of things in array
string = "$xena is here $x and $y."
我有另外一個數組用東西替換那些東西,讓我們說它叫做rep_array。
rep_array = [3, "A", "B", "C"]
對於替換我使用這個:
for x in range (1, array[0] + 1):
string = string.replace(array[x], rep_array[x])
但結果是:
string = "Aena is here A and B."
但是我需要的只是孤獨的$ x而不是$ x。 結果應如下所示:
string = "$xena is here A and B."
注意:
array
所有模式都以$
開頭。 $
后的整個單詞,則匹配一個模式; $xena
與$x
不匹配,但foo$x
會匹配。 $
可以使用@
進行轉義而不應該匹配(例如$x
與@$x
不匹配) 這不是你問題的直接答案,但正如我猜你會得到其他解決方案黑客攻擊\\b
,我會建議你一個更加pythonic的解決方案:
rep_dict = {'x': 'A', 'y': 'B', 'hi_buddy': 'C'}
string = '{xena} is here {x} and {y}'
print string.format(rep_dict)
但在這里,它將會引發KeyError
失蹤的齊娜rep_dict
,可以所要解決的回答這個問題 ,使用defaultdict
或者您可以根據需要你的使用情況更喜歡格式化。
使用$
的問題在於,制作與未定義真實邊界相匹配的東西並非易事。 大多數使用$
變量的語言將它應用於下一個字符,使用較大字符(即shell和makefile)的邊界,即${xena}
。 像Perl這樣的語言使用語法來定義$
變量的上下文,我猜他們也可以在tokenizer中使用regexp。
這就是為什么在python中,我們只使用格式化運算符來標記字符串中變量{}
的邊界,沒有無用的$
所以我們不必處理歧義( $xena => ${x}ena or ${xena}?
)。
HTH
使用一個正則表達式,用一些空白的look-behind和\\b
anchor包裝你的源文本; 確保也包括字符串的開頭:
import re
for pattern, replacement in zip(array[1:], rep_array[1:]):
pattern = r'{}\b'.format(re.escape(pattern))
string = re.sub(pattern, replacement, string)
這使用re.escape()
來確保模式中的任何正則表達式元字符首先被轉義。 zip()
用於配對模式和替換值; 你的range()
循環的更pythonic替代。
\\b
僅匹配單詞字符后跟非單詞字符(反之亦然)的位置,即單詞邊界 。 你的模式都以單詞字符結尾,所以這確保你的模式只有在下一個字符不是單詞字符時才匹配,阻止$x
在$xena
匹配。
演示:
>>> import re
>>> array = [3, "$x" , "$y", "$hi_buddy"]
>>> rep_array = [3, "A", "B", "C"]
>>> string = "$xena is here $x and $y. foo$x matches too!"
>>> for pattern, replacement in zip(array[1:], rep_array[1:]):
... pattern = r'{}\b'.format(re.escape(pattern))
... string = re.sub(pattern, replacement, string)
...
>>> print string
$xena is here A and B. fooA matches too!
string.replace
不知道正則表達式,所以你必須使用re
模塊( https://docs.python.org/3.4/library/re.html ),即re.sub
方法:
>>>re.sub(r"\$x\b", "replace", r"$xenia $x")
'$xenia replace'
你也可以嘗試這樣的事情:
import re
search = ["$x" , "$y", "$hi_buddy"]
replace = ["A", "B", "C"]
string = "$xena is here $x and $y skip$x."
repl = dict(zip(search, replace))
print re.sub(r'\B\$\w+', lambda m: repl.get(m.group(0), m.group(0)), string)
# result: $xena is here A and B skip$x.
\\B
這里的意思是“當它前面有一個非單詞字符時匹配$”。 如果您還需要skip$x
進行替換,只需刪除\\B
:
print re.sub(r'\$\w+', lambda m: repl.get(m.group(0), m.group(0)), string)
# $xena is here A and B skipA.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.