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