Python替换,使用数组中的模式
我需要使用数组替换字符串中的某些内容,它们可以如下所示:Python替换,使用数组中的模式,python,arrays,regex,replace,Python,Arrays,Regex,Replace,我需要使用数组替换字符串中的某些内容,它们可以如下所示: array = [3, "$x" , "$y", "$hi_buddy"] #the first number is number of things in array string = "$xena is here $x and $y." string = "$xena is here A and B." import re search = ["$x" , "$y", "$hi_buddy"] replace = ["A", "
array = [3, "$x" , "$y", "$hi_buddy"]
#the first number is number of things in array
string = "$xena is here $x and $y."
string = "$xena is here A and B."
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.
我有另一个数组,用一些东西来代替这些东西,比如说它叫rep_数组
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美元。
结果应该如下所示:
array = [3, "$x" , "$y", "$hi_buddy"]
#the first number is number of things in array
string = "$xena is here $x and $y."
string = "$xena is here A and B."
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.
请注意:
数组中的所有图案都以
开头$
- 如果模式匹配
之后的整个单词,则模式匹配$
不匹配$xena
,但$x
会匹配foo$x
可以用$
转义,但不应匹配(例如@
不匹配$x
)@$x
rep_dict = {'x': 'A', 'y': 'B', 'hi_buddy': 'C'}
string = '{xena} is here {x} and {y}'
print string.format(rep_dict)
但在这里,它将针对rep_dict
中缺少的xena引发键错误,这可以通过使用defaultdict
或您可能喜欢的格式化程序来解决,具体取决于您的用例
使用$
的问题在于,使某些内容与不定义真实边界的内容相匹配并非小事。大多数使用$
变量的语言将其应用于下一个字符,在较大的字符(即shell和makefile)上使用边界,即${xena}
。像Perl这样的语言使用语法来定义$
变量的上下文,我猜它们也可能在标记器中使用regexp
这就是为什么在python中,我们只使用格式化运算符来标记字符串中变量{}
的边界,而没有无用的$
,因此我们不必处理歧义($xena=>${x}ena或${xena}?
)
HTHstring.replace
不知道正则表达式,因此必须使用re
模块(),即re.sub
方法:
>>>re.sub(r"\$x\b", "replace", r"$xenia $x")
'$xenia replace'
使用一个正则表达式,用一些空格和\b
锚来包装源文本;确保也包括字符串的开头:
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()
循环的另一个更具Python风格的选择
\b
仅在单词字符后跟非单词字符(反之亦然)的位置匹配,即单词边界。您的模式都以单词字符结尾,因此这确保您的模式仅在下一个字符不是单词字符时匹配,从而阻止$x
内部的匹配$xena
演示:
您也可以尝试以下方法:
array = [3, "$x" , "$y", "$hi_buddy"]
#the first number is number of things in array
string = "$xena is here $x and $y."
string = "$xena is here A and B."
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
这里的意思是“在前面加上非单词字符时匹配$”。如果还需要替换跳过$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.
你所有的替换模式都是从$
开始的吗?为什么你不使用python,而不是重新发明轮子呢?@MartijnPieters:那么“\$x”呢?在替换数组中你会有一个“?@npinti:对不起,我不明白你的意思。@Alfe:这就是为什么我问模式是否总是以$
开头。这也将匹配foo$x
中的$x
。我需要替换foo$x,但不知道转义“\”如何进入数组。@Whitedracke:这是一个重要的细节;一定要在你的问题帖中包括这一点@怀特德拉克:我更新了你的帖子,加入了这个细节,以及所有模式都以$
开头的事实。这是一个细节,在什么是正确的解决方案和什么不是很大。当然,我给这个OP知道并考虑使用它,如果它可以是一个选项给他,和未来读者可能会考虑使用<代码> $< /Case>变量在字符串中使用的字符串格式已经建立了。这是正确的TOOWTDI(),如果OP对输入字符串有任何控制权。使用\B
意味着$$x
也匹配。@MartijnPieters:对,也是$x
,…$x
及类似产品。从这个问题上我不明白这是否是一种期望的行为。你的解决方案几乎符合我的需要,我还需要能够用@逃离美元,你能告诉我这种模式有什么问题吗?pattern=r'(?:([^@])|^{}\b.format(re.escape(pattern))@Whitedracke:您需要查看后面的代码:r'(?:(?@Whitedracke:或者更好的是,查看后面的负面代码:r'(?)?