python正则表达式替换匹配字符串的一部分

时间:2010-12-20 11:12:48

标签: python regex string

我有一个可能看起来像这样的字符串

"myFunc('element','node','elementVersion','ext',12,0,0)"

我目前正在检查有效性,这可以正常使用

myFunc\((.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\,(.+?)\)

现在我想替换第3个参数的任何字符串。 不幸的是,我不能在第三个位置的任何子字符串上使用stringreplace,因为相同的“子字符串”可能是该字符串中的任何其他位置。

用这个和re.findall,

myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)

我能够在第3个位置获取子字符串的内容,但是re.sub不会替换字符串,它只返回我想要替换的字符串:/

这是我的代码

myRe = re.compile(r"myFunc\(.+?\,.+?\,(.+?)\,.+?\,.+?\,.+?\,.+?\)")
val =   "myFunc('element','node','elementVersion','ext',12,0,0)"

print myRe.findall(val)
print myRe.sub("noVersion",val)

知道我错过了什么吗?

谢谢! SEB

5 个答案:

答案 0 :(得分:7)

在re.sub中,您需要为整个匹配字符串指定替换。这意味着您需要重复您不想替换的部分。这有效:

myRe = re.compile(r"(myFunc\(.+?\,.+?\,)(.+?)(\,.+?\,.+?\,.+?\,.+?\))")
print myRe.sub(r'\1"noversion"\3', val)

答案 1 :(得分:4)

如果您唯一的工具是锤子,所有问题看起来都像钉子。正则表达式是一个强大的锤子,但不是每项任务的最佳工具。

解析器可以更好地处理某些任务。在这种情况下,字符串中的参数列表就像一个Python元组,你可以作弊:使用Python内置解析器:

>>> strdata = "myFunc('element','node','elementVersion','ext',12,0,0)"
>>> args = re.search(r'\(([^\)]+)\)', strdata).group(1)
>>> eval(args)
('element', 'node', 'elementVersion', 'ext', 12, 0, 0)

如果您不相信输入ast.literal_eval比eval更安全。一旦你在字符串中对参数列表进行了解构,我认为如果需要,你可以弄清楚如何再次操作和重组它。

答案 2 :(得分:2)

阅读文档:re.sub返回字符串的副本,其中整个模式的每次出现都替换为替换。它无论如何都不能修改原始字符串,因为Python字符串是不可变的。

尝试使用前瞻和后瞻断言来构造仅与元素本身匹配的正则表达式:

myRe = re.compile(r"(?<=myFunc\(.+?\,.+?\,)(.+?)(?=\,.+?\,.+?\,.+?\,.+?\))")

答案 3 :(得分:1)

如果你想在不使用正则表达式的情况下这样做:

>>> s = "myFunc('element','node','elementVersion','ext',12,0,0)"
>>> l = s.split(",")
>>> l[2]="'noVersion'"
>>> s = ",".join(l)
>>> s
"myFunc('element','node','noVersion','ext',12,0,0)"

答案 4 :(得分:0)

您是否尝试过使用命名组? http://docs.python.org/howto/regex.html#search-and-replace

希望这会让你只针对第三场比赛。