【问题标题】:python re.sub, only replace part of match [duplicate]python re.sub,只替换部分匹配[重复]
【发布时间】:2015-12-18 08:28:59
【问题描述】:

我对python很陌生

我需要用一个正则表达式匹配所有情况并进行替换。这是一个示例子字符串 --> 期望的结果:

<cross_sell id="123" sell_type="456"> --> <cross_sell>

我正在尝试在我的代码中执行此操作:

myString = re.sub(r'\<[A-Za-z0-9_]+(\s[A-Za-z0-9_="\s]+)', "", myString)

它不会替换&lt;cross_sell 之后的所有内容,而是替换所有内容并返回'&gt;'

有没有办法让 re.sub 只替换捕获组而不是整个模式?

【问题讨论】:

  • 输入数据是XML吗?谢谢。
  • 我正在读取一个 xml 文件并将其放入一个字符串中
  • 如果我希望我的输出为 即我想用 mystring 替换 cross_cell

标签: python regex python-2.7


【解决方案1】:

您可以使用组引用来匹配第一个单词,并使用否定字符类来匹配 &lt;&gt; 之间的其余字符串:

>>> s='<cross_sell id="123" sell_type="456">'
>>> re.sub(r'(\w+)[^>]+',r'\1',s)
'<cross_sell>'

\w 等于 [A-Za-z0-9_]

【讨论】:

  • 请致电\w+
  • 不能简化成re.sub(r'(\w+)[^&gt;]+',r'\1',s)吗?
  • @maccinza 确实,不错!
  • @maccinza -- 对于输入文本,它可以被简化......但是,我不确定你是否想要进行一般的替换......(谁知道标签看起来像?)
【解决方案2】:

您可以使用替换组:

>>> my_string = '<cross_sell id="123" sell_type="456"> --> <cross_sell>'
>>> re.sub(r'(\<[A-Za-z0-9_]+)(\s[A-Za-z0-9_="\s]+)', r"\1", my_string)
'<cross_sell> --> <cross_sell>'

请注意,我将第一组(您要保留的组)放在括号中,然后在替换字符串中使用 "\1" 修饰符(第一组)将其保留在输出中。

【讨论】:

  • 漂亮的答案!
  • 如果我希望我的输出为 即我想用 mystring 替换 cross_cell
【解决方案3】:

由于输入数据是XML,最好用XML解析器解析。

内置xml.etree.ElementTree 是一种选择:

>>> import xml.etree.ElementTree as ET
>>> data = '<cross_sell id="123" sell_type="456"></cross_sell>'
>>> cross_sell = ET.fromstring(data)
>>> cross_sell.attrib = {}
>>> ET.tostring(cross_sell)
'<cross_sell />'

lxml.etree 是另一种选择。

【讨论】:

    【解决方案4】:

    以下代码在python 3.6下测试,没有使用组..

    test = '<cross_sell id="123" sell_type="456">'
    resp = re.sub(r'\w+="\w+"' ,r'',test)
    print (resp)
    
    <cross_sell>
    

    【讨论】:

      猜你喜欢
      • 2022-12-04
      • 2012-08-15
      • 2019-06-08
      • 2011-02-15
      • 2014-06-26
      相关资源
      最近更新 更多