簡體   English   中英

Python替換,使用數組中的模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM