【问题标题】:python regular expression replacing part of a matched stringpython正则表达式替换匹配字符串的一部分
【发布时间】:2011-05-28 04:58:05
【问题描述】:

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

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

我目前正在检查有效性,它工作正常

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

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

有了这个和一个 re.findall,

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

我能够在第三个位置获取子字符串的内容,但是 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)

知道我错过了什么吗?

谢谢! 赛博

【问题讨论】:

  • 这里的各种答案让我相信 Pythonic 对 Perl 的 TIMTOWTDI 座右铭的反抗有点被误导了。 :)

标签: python regex string


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    解析器可以更好地处理某些任务。在这种情况下,字符串中的参数列表就像一个 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 更安全。一旦你解构了字符串中的参数列表,我想你可以弄清楚如何在需要时再次操作和重新组装它。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

      • 如果某个参数有可能包含逗号,则正则表达式方法会越来越难。
      【解决方案4】:

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

      希望这会让你只瞄准第三场比赛。

      【讨论】:

        【解决方案5】:

        如果您想在不使用正则表达式的情况下执行此操作:

        >>> 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)"
        

        【讨论】:

        • 如果第一个参数是 'ele,ment' 怎么办?
        • 那么,所有的答案,包括正则表达式的答案,都失败了。 :)
        • 你是对的!这就是为什么我认为解析器比正则表达式更适合这项任务。
        • @Paulo,是的,解析器,如果可用于手头的工作,应该优先于正则表达式。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-30
        • 2015-02-03
        • 2023-04-07
        • 2012-11-25
        • 1970-01-01
        相关资源
        最近更新 更多