【问题标题】:Extract multiple occurrences of a substring using Powershell使用 Powershell 提取多次出现的子字符串
【发布时间】:2018-05-09 21:52:22
【问题描述】:

给定以下字符串:

'<p><a href="china">China</a><br><a href="india">India</a><br><a
href="korea">Korea</a><br><a href="malaysia">Malaysia</a><br><a
href="thailand">Thailand</a></p>'

我想使用 Powershell 提取其中列出的所有国家/地区。也就是说我想返回@(China,India,Korea,Malaysia,Thailand)。

曾尝试使用正则表达式但找不到正确的模式,例如:

'<p><a href="china">China</a><br><a href="india">India</a><br><a href="korea">Korea</a><br><a href="malaysia">Malaysia</a><br><a href="thailand">Thailand</a></p>'  -match '(<a href="[A-Z a-z]*">[A-Z a-z]*</a>)+'
$matches

返回:

Name                           Value                                                                                                                                                                                            
----                           -----                                                                                                                                                                                            
1                              <a href="china">China</a>                                                                                                                                                                        
0                              <a href="china">China</a>

有什么建议吗?正则表达式是正确的方法吗?

附:请注意,sn-p 的格式不正确,因此我不能简单地将其转换为 XML。

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    $Matches 自动变量包含有关上次 -match 操作的匹配捕获组的信息,而不是有关匹配的信息。如果你想得到多个模式匹配,那么你必须使用[Regex]类中的Matches方法:

    $InputString='<p><a href="china">China</a><br><a href="india">India</a><br><a href="korea">Korea</a><br><a href="malaysia">Malaysia</a><br><a href="thailand">Thailand</a></p>'
    $Pattern='<a href="[A-Z a-z]*">([A-Z a-z]*)</a>'
    $Countries=[Regex]::Matches($InputString,$Pattern)|ForEach-Object {$_.Groups[1].Value}
    $Countries
    

    虽然为了解析 HTML,您最好使用一些 HTML 解析器,如 other answer 向您建议的那样。

    【讨论】:

    • 啊,我明白了。再次感谢。
    【解决方案2】:

    以下正则表达式应该可以解决问题:

    (?<=><a\shref="\w+">)\w+
    

    机器学习

    【讨论】:

      【解决方案3】:

      正则表达式从来都不是处理 HTML 的好方法(尽管它们通常很诱人)。您可以在不使用任何正则表达式的情况下解析 HTML 并提取所需的数据:

      PS C:\> $d = '<p><a href="china">China</a><br><a href="india">India</a><br><a
      href="korea">Korea</a><br><a href="malaysia">Malaysia</a><br><a
      href="thailand">Thailand</a></p>'
      
      
      PS C:\> $html = New-Object -ComObject "HTMLFile"
      
      PS C:\> $html.IHTMLDocument2_write($d)
      
      PS C:\> $html.getElementsByTagName('A') | select -expandProperty innerText
      China
      India
      Korea
      Malaysia
      Thailand
      

      【讨论】:

      • 不错。不知道expandProperty。谢谢邓肯。
      • 大多数情况下使用 Powershell 3 及更高版本,您不需要使用 expandProperty,因为您通常可以只使用点表示法。我不知道为什么它在这里不起作用:($html.getElementsByTagName('A')).innerText 什么也没提供,而 $html.getElementsByTagName('A') | select -expandProperty innerText 工作正常。我想一定是因为$html是一个COM对象。
      【解决方案4】:
      $InputString='<p><a href="china">China</a><br><a href="india">India</a><br><a href="korea">Korea</a><br><a href="malaysia">Malaysia</a><br><a href="thailand">Thailand</a></p>'
      $Pattern='(?<=>)\w+?(?=<)'
      
      ([Regex]::Matches($InputString,$Pattern)).Value
      

      中国

      印度

      韩国

      马来西亚

      泰国

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-28
        • 2016-07-25
        • 1970-01-01
        • 1970-01-01
        • 2020-12-02
        • 2015-06-08
        • 2014-10-12
        • 2011-02-15
        相关资源
        最近更新 更多