PowerShell去除字符串内容中的HTML标签

10
我有一个巨大的HTML数据字符串,被分成小块。我正在尝试编写PowerShell脚本来删除所有HTML标签,但是很难找到正确的正则表达式模式。
示例字符串:
<p>This is an example</br>of various <span style="color: #445444">html content</span>

我尝试过使用:
$string -replace '\<([^\)]+)\>',''

它可以处理简单的例子,但像上面这样的例子会捕获整个字符串。

有什么建议可以实现这一点吗?

提前感谢。

3个回答

23

对于一个纯正则表达式,它应该像这样容易:<[^>]+>

$string -replace '<[^>]+>',''

正则表达式可视化

Debuggex Demo

请注意,这可能无法处理某些HTML注释或<pre>标签的内容。

相反地,您可以使用HTML Agility Pack替代链接),该工具是为在.NET代码中使用而设计的,我以前在PowerShell中成功使用过它:

Add-Type -Path 'C:\packages\HtmlAgilityPack.1.4.6\lib\Net40-client\HtmlAgilityPack.dll'

$doc = New-Object HtmlAgilityPack.HtmlDocument
$doc.LoadHtml($string)
$doc.DocumentNode.InnerText

HTML Agility Pack 能够很好地处理非完美的 HTML。


你最终使用了正则表达式还是解析器? - briantist
我使用了正则表达式,目前它运行良好,因为我的脚本已经相当大了,而且我正在手动解析HTML,但这个库看起来非常不错,我会在我的其他项目中尝试使用,谢谢。 - Arturski
这里在SO上有相当数量关于Agility Pack的其他问题,所以你可以在这里找到更多帮助或者发布相关内容。其中许多问题是针对C#的,但它们仍然适用于Powershell的使用。这是一个非常好的库,但要熟悉XPath才能充分利用它。 - briantist
HTML Agility Pack的链接对我来说是失效的。它可以在NuGet上获取:https://www.nuget.org/packages/HtmlAgilityPack/ - donothingsuccessfully
不要做无用功。对我来说,链接仍然有效,但我已添加了你的链接作为另一种选择。谢谢! - briantist

3
为了解决umlauts和特殊字符,我使用了html Object。这是我的函数:
Function ConvertFrom-Html
{
    <#
        .SYNOPSIS
            Converts a HTML-String to plaintext.

        .DESCRIPTION
            Creates a HtmlObject Com object und uses innerText to get plaintext. 
            If that makes an error it replaces several HTML-SpecialChar-Placeholders and removes all <>-Tags via RegEx.

        .INPUTS
            String. HTML als String

        .OUTPUTS
            String. HTML-Text als Plaintext

        .EXAMPLE
        $html = "<p><strong>Nutzen:</strong></p><p>Der&nbsp;Nutzen ist &uuml;beraus gro&szlig;.<br />Test ob 3 &lt; als 5 &amp; &quot;4&quot; &gt; &apos;2&apos; it?"
        ConvertFrom-Html -Html $html
        $html | ConvertFrom-Html

        Result:
        "Nutzen:
        Der Nutzen ist überaus groß.
        Test ob 3 < als 5 ist & "4" > '2'?"


        .Notes
            Author: Ludwig Fichtinger FILU
            Inital Creation Date: 01.06.2021
            ChangeLog: v2 20.08.2021 try catch with replace for systems without Internet Explorer

    #>

    [CmdletBinding(SupportsShouldProcess = $True)]
    Param(
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, HelpMessage = "HTML als String")]
        [AllowEmptyString()]
        [string]$Html
    )

    try
    {
        $HtmlObject = New-Object -Com "HTMLFile"
        $HtmlObject.IHTMLDocument2_write($Html)
        $PlainText = $HtmlObject.documentElement.innerText
    }
    catch
    {
        $nl = [System.Environment]::NewLine
        $PlainText = $Html -replace '<br>',$nl
        $PlainText = $PlainText -replace '<br/>',$nl
        $PlainText = $PlainText -replace '<br />',$nl
        $PlainText = $PlainText -replace '</p>',$nl
        $PlainText = $PlainText -replace '&nbsp;',' '
        $PlainText = $PlainText -replace '&Auml;','Ä'
        $PlainText = $PlainText -replace '&auml;','ä'
        $PlainText = $PlainText -replace '&Ouml;','Ö'
        $PlainText = $PlainText -replace '&ouml;','ö'
        $PlainText = $PlainText -replace '&Uuml;','Ü'
        $PlainText = $PlainText -replace '&uuml;','ü'
        $PlainText = $PlainText -replace '&szlig;','ß'
        $PlainText = $PlainText -replace '&amp;','&'
        $PlainText = $PlainText -replace '&quot;','"'
        $PlainText = $PlainText -replace '&apos;',"'"
        $PlainText = $PlainText -replace '<.*?>',''
        $PlainText = $PlainText -replace '&gt;','>'
        $PlainText = $PlainText -replace '&lt;','<'
    }

    return $PlainText
}

示例:

"<p><strong>Nutzen:</strong></p><p>Der&nbsp;Nutzen ist &uuml;beraus gro&szlig;.<br />Test ob 3 &lt; als 5 ist &amp; &quot;4&quot; &gt; &apos;2&apos;?" | ConvertFrom-Html

结果:

Nutzen:
Der Nutzen ist überaus groß.
Test ob 3 < als 5 ist & "4" > '2'?

Ludwig,你太棒了!! - microset

1
你可以尝试这个:

$string -replace '<.*?>',''

3
小心使用 .*,这是一种匹配效率较低的方式。如果你知道结束分隔符,那么在所选答案中使用的否定字符集 ( [^>] ) 意味着引擎只需要寻找一个字符来停止匹配,而不必回溯以匹配后面的 '>'。 - Ashley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接