【问题标题】:How to delete the words between two delimiters?如何删除两个分隔符之间的单词?
【发布时间】:2012-01-09 05:48:28
【问题描述】:

我有一个嘈杂的数据..类似于

<@ """@$ FSDF >something something <more noise>

现在我只想提取"something something"。 有没有办法删除这两个分隔符 "&lt;""&gt;" 之间的文本?

【问题讨论】:

  • 数据总是每行一个的那种形式吗?
  • 您要提取“某事某事”还是删除“”分隔符之间的文本?
  • 嗨..数据有多行..基本上是一个巨大的文件我想提取“一些东西”但是使用重新和漂亮的汤..突然让我留下空白文件..不太清楚为什么..但是如果我可以删除“”之间的文本,那么这也有同样的目的:)
  • @Fraz BeautifulSoup 处理 html 源代码中的匹配标签,因此它可能无法帮助解析由 '' 包围的随机文本。
  • 请避免 "Give me the codez" 问题,这些问题已经被问了很多次并得到了回答,您必须努力避免找到答案。而是显示您正在处理的脚本并说明问题所在。另见How much research effort is expected of Stack Overflow users?

标签: python


【解决方案1】:

使用regular expressions:

>>> import re
>>> s = '<@ """@$ FSDF >something something <more noise>'
>>> re.sub('<[^>]+>', '', s)
'something something '

[更新]

如果您尝试过像&lt;.+&gt; 这样的模式,其中点表示任何字符,加号表示一个或多个,您就会知道它不起作用。

>>> re.sub(r'<.+>', s, '')
''

为什么!?!发生这种情况是因为正则表达式默认情况下是“贪婪的”。该表达式将匹配字符串结尾之前的任何内容,包括&gt; - 这不是我们想要的。我们想要匹配&lt; 并在下一个&gt; 处停止,所以我们使用[^x] 模式,意思是“除x 之外的任何字符”(x 是&gt;)。

? 运算符将匹配变为“非贪婪”,因此具有相同的效果:

>>> re.sub(r'<.+?>', '', s)
'something something '

前一个更明确,这个少打字;请注意,x? 表示 x 出现 0 次或 1 次。

【讨论】:

  • 如果每个正则表达式的答案都解释了为什么正则表达式首先起作用,就像你所做的那样,那么这将是一个更快乐的地方。 +1!
【解决方案2】:

当然,你可以使用正则表达式。

import re
s = #your string here
t = re.sub('<.*?>', '', s)

上面的代码应该可以做到。

【讨论】:

    【解决方案3】:

    首先感谢 Paulo Scardine,我用你的 re 做了一件很棒的事。想法是让 LibreOffice po 文件无标签以用于打印目的。我制作了以下脚本,它将清理帮助文件以获得更小更容易的帮助文件。

    import re
    f = open('a.csv')
    text = f.read()
    f.close()
    
    clean = re.sub('<[^>]+>', ' ', text)
    
    f = open('b.csv', 'w')
    f.write(clean)
    f.close()
    

    【讨论】:

      【解决方案4】:
      import re
      my_str = '<@ """@$ FSDF >something something <more noise>'
      re.sub('<.*?>', '', my_str)
      'something something '
      

      re.sub 函数采用正则表达式并将字符串中的所有匹配项替换为第二个参数。在这种情况下,我们正在搜索 &lt;&gt; ('&lt;.*?&gt;') 之间的所有字符,并将它们替换为空 ('')。

      ?re 中用于非贪婪搜索。

      更多关于re module


      如果“噪音”实际上是 html 标签,我建议你查看BeautifulSoup

      【讨论】:

        【解决方案5】:

        为了兴趣,你可以写一些代码,例如:

        with open('blah.txt','w') as f:
            f.write("""<sdgsa>one<as<>asfd<asdf>
        <asdf>two<asjkdgai><iasj>three<fasdlojk>""")
        
        def filter_line(line):
            count=0
            ignore=False
            result=[]
            for c in line:
                if c==">" and count==1:
                    count=0
                    ignore=False
                if not ignore:
                    result.append(c)
                if c=="<" and count==0:
                    ignore=True
                    count=1
            return "".join(result)
        
        with open('blah.txt') as f:
            print "".join(map(filter_line,f.readlines()))
        
        >>> 
        <>one<>asfd<>
        <>two<><>three<>
        

        【讨论】:

        • 是的,我决定他们可能想要第二个">"例如如果你有myname->bob,你会得到myname->bob,在另一种情况下你只会得到'bob'。解析损坏的 xml 真的很不理想。如果““标签之间有换行符,我的代码也会失败。感谢您阅读我的代码