移除字符串中除首次出现外的所有实例

2 投票
2 回答
3894 浏览
提问于 2025-04-17 08:35

在Python中,我想从一个字符串中去掉所有的"<html>"(除了第一次出现的那个)。

另外,我还想去掉字符串中的所有"</html>"(除了最后一次出现的那个)。

而且"<html>"可能是大写的,所以我需要不区分大小写。

我该怎么做比较好呢?

2 个回答

5

要从字符串 s 中去掉除了第一次出现的 <html> 以外的所有 <html>,你可以使用下面的代码:

substr = "<html>"
try:
    first_occurrence = s.index(substr) + len(substr)
except ValueError:
    pass
else:
    s = s[:first_occurrence] + s[first_occurrence:].replace(substr, "")

要去掉除了最后一次出现的 </html> 以外的所有 </html>,也可以用类似的方法:

substr = "</html>"
try:
    last_occurrence = s.rindex(substr)
except ValueError:
    pass
else:
    s = s[:last_occurrence].replace(substr, "") + s[last_occurrence:]

你可能想用空格来替换这些出现的地方,而不是用空字符串。

3

这个解决方案使用了两个正则表达式。第一个正则表达式把整个文件或字符串分成三个部分:

  1. 第一部分(捕获到组 $1)是从字符串开始到第一个HTML开始标签的所有内容。
  2. 第二部分(捕获到组 $2)是从第一个HTML开始标签之后到最后一个HTML结束标签之前的所有内容。
  3. 第三部分(捕获到组 $3)包括最后一个HTML结束标签和后面直到文件或字符串结束的所有内容。

这个函数首先尝试把正则表达式应用到输入的文本上。如果匹配成功,接下来会用第二个正则表达式去掉外层HTML元素的开始和结束标签(这些内容之前已经捕获到组2中)。然后,使用这三个部分重新组合字符串(中间的部分已经去掉了HTML标签)。

def stripInnermostHTMLtags(text):
    '''Strip all but outermost HTML start and end tags.
    '''
    # Regex to match outermost HTML element and its contents.
    p_outer = re.compile(r"""
        ^                 # Anchor to start of string.
        (.*?<html[^>]*>)  # $1: Outer HTML start tag.
        (.*)              # $2: Outer HTML element contents.
        (</html\s*>.*)    # $3: Outer HTML end tag.
        $                 # Anchor to end of string.
        """, re.DOTALL | re.VERBOSE | re.IGNORECASE)
    # Split text into outermost HTML tags and its contents.
    m = p_outer.match(text)
    if m:
        # Regex to match HTML element start or end tag.
        p_inner = re.compile("</?html[^>]*>", re.IGNORECASE)
        # Strip contents of any/all HTML start and end tags.
        contents = p_inner.sub("", m.group(2))
        # Put string back together stripped of inner HTML tags.
        text = m.group(1) + contents + m.group(3)
    return text

需要注意的是,这个解决方案可以正确处理HTML开始标签中的任何属性。同时,这个解决方案并不处理属性值中包含 > 字符的HTML标签(不过这种情况应该很少见)。

撰写回答