繁体   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