【问题标题】:Powershell remove HTML tags in string contentPowershell 删除字符串内容中的 HTML 标签
【发布时间】:2015-07-07 22:33:02
【问题描述】:

我有一个大的 HTML 数据字符串分成小块。我正在尝试编写一个 PowerShell 脚本来删除所有 HTML 标记,但发现很难找到正确的正则表达式模式。

示例字符串:

<p>This is an example</br>of various <span style="color: #445444">html content</span>

我尝试过使用:

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

它适用于简单的示例,但上面的示例捕获整个字符串。

对实现这一目标的最佳方法有什么建议吗?

提前致谢

【问题讨论】:

    标签: html regex string powershell


    【解决方案1】:

    为了解决变音符号和特殊字符,我使用了一个 html 对象。这是我的功能:

    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'?
    

    【讨论】:

    • 路德维希,你太棒了!!
    【解决方案2】:

    对于纯正则表达式,它应该像&lt;[^&gt;]+&gt; 一样简单:

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

    Debuggex Demo

    请注意,某些 HTML cmets 或 &lt;pre&gt; 标记的内容可能会失败。

    相反,您可以使用HTML Agility Pack (alternative link),它专为在 .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 敏捷包适用于不完美的 HTML。

    【讨论】:

    • 您最终使用的是正则表达式还是解析器?
    • 我使用了正则表达式,到目前为止它运行良好,因为我的脚本已经很大,我正在手动解析 html,但是库看起来很好,我会在我的其他项目中尝试,谢谢
    • 这里还有很多关于敏捷包的其他问题,因此您可以在此处找到更多帮助或发布相关信息。其中许多将是 C# 特定的,但它们仍然适用于 Powershell 使用。这是一个相当不错的库,但一定要复习 XPath 以充分利用它。
    • HTML Agility Pack 的链接对我来说已损坏。它在 nuget 上可用:nuget.org/packages/HtmlAgilityPack
    • donothingsuccessfully 该链接仍然对我有效,但添加了您的作为替代;谢谢!
    【解决方案3】:

    你可以试试这个:

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

    【讨论】:

    • 小心使用 .* 像这样。这是一种效率较低的匹配方式。如果您知道结束分隔符,则所选答案中的否定字符集 ( [^>] ) 意味着引擎只是在寻找一个字符来停止匹配,而不是稍后回溯以匹配“>”。
    猜你喜欢
    • 2022-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2021-02-05
    相关资源
    最近更新 更多