【问题标题】:Match particular CDATA sections in XML data匹配 XML 数据中的特定 CDATA 部分
【发布时间】:2015-10-07 22:15:45
【问题描述】:

我正在尝试执行 PowerShell 正则表达式,我想要从中进行匹配的以下页面(下文进一步),粗体的两个部分是我想要捕获并分配给变量的信息。所以我需要两个正则表达式。从下面的文字中,我需要准确找到的两个区域是 KingYears & Years。请注意,这两个区域发生了变化(因此我需要捕获它们),其余代码保持不变。

这是我目前拥有的正则表达式,但它对我不起作用。

\s+artist\s*>\s*<\s*!\s*[CDATA\s*[(.*)\s*]\s*]\s*>\s*<\s*/artist

这是我尝试使用正则表达式的页面(或数据)。

<on_air>
  <publishedInfo publishedDate="2015-07-18 16:24:28" />
  <stationName><![CDATA[Mix 106.5]]></stationName>
  <stationPrefix><![CDATA[mix1065]]></stationPrefix>
  <generic_coverart><![CDATA[http://media.arn.com.au/images/getImage.aspx?i=generic_mix1065.jpg]]></generic_coverart>
  <now_playing>
    <audio ID="id_1705168034_30458146" type="song">
      <title generic="False"><![CDATA[King*]]></title>
      <artist><![CDATA[Years & Years]]></artist>
      <number><![CDATA[46029]]></number>
      <cut><![CDATA[1]]></cut>
      <ref><![CDATA[]]></ref>
      <played_datetime><![CDATA[2015-07-18 16:24:27]]></played_datetime>
      <length><![CDATA[00:03:28]]></length>
      <coverart generic="true"><![CDATA[http://media.arn.com.au/images/getImage.aspx?i=generic_mix1065.jpg]]></coverart>
      <options>
        <option><![CDATA[KIIS S Integrated]]></option>
      </options>
    </audio>
  </now_playing>

【问题讨论】:

    标签: regex xml powershell powershell-3.0 cdata


    【解决方案1】:

    如果它是一个有效的 XML,那么你不需要使用正则表达式。 PowerShell 适应 XML 对象,您可以使用标准属性语法在它们上导航:

    $xml=[xml]@'
    <on_air>
      <publishedInfo publishedDate="2015-07-18 16:24:28" />
      <stationName><![CDATA[Mix 106.5]]></stationName>
      <stationPrefix><![CDATA[mix1065]]></stationPrefix>
      <generic_coverart><![CDATA[http://media.arn.com.au/images/getImage.aspx?i=generic_mix1065.jpg]]></generic_coverart>
      <now_playing>
        <audio ID="id_1705168034_30458146" type="song">
          <title generic="False"><![CDATA[King*]]></title>
          <artist><![CDATA[Years & Years]]></artist>
          <number><![CDATA[46029]]></number>
          <cut><![CDATA[1]]></cut>
          <ref><![CDATA[]]></ref>
          <played_datetime><![CDATA[2015-07-18 16:24:27]]></played_datetime>
          <length><![CDATA[00:03:28]]></length>
          <coverart generic="true"><![CDATA[http://media.arn.com.au/images/getImage.aspx?i=generic_mix1065.jpg]]></coverart>
          <options>
            <option><![CDATA[KIIS S Integrated]]></option>
          </options>
        </audio>
      </now_playing>
    </on_air>
    '@
    $xml.on_air.now_playing.audio.title.'#cdata-section'
    $xml.on_air.now_playing.audio.artist.'#cdata-section'
    

    【讨论】:

    • 嗨 PetSerAl,我可以给你 who URI - media.arn.com.au/xml/mix1011_now.xml 这已经是 XML,基于这个 URI,你能给我一个导出的方法吗艺术家和标题并应用于一个变量(每个艺术家和标题一个变量)。我想我需要使用 Invoke-WebRequest
    • 要加载 XML,您可以使用:$xml=New-Object xml;$xml.Load('http://media.arn.com.au/xml/mix1011_now.xml')。比您可以在我的答案中显示的方式导航它。
    【解决方案2】:

    你想转义括号文字。

    此外,当您的意图更具体时,最好避免使用点“匹配几乎任何字符”元字符。在您的情况下,您真正​​想要做的是匹配直到您点击右括号,因此指定以下内容更安全:

    '\s+artist\s*>\s*<\s*!\s*\[CDATA\s*\[([^]]*)\s*\]\s*\]\s*>\s*<\s*\/artist'
    

    注意:正则表达式是上下文相关的,所以我不必在字符类中转义右括号的原因是因为它的位置,即是在否定类中指定的第一个字符——在这种情况下,它不能是字符类的右括号。换句话说,它不是模棱两可的。

    【讨论】:

    • 谢谢...并感谢您的解释。我会读几遍让它吸收。
    • 当然,所以\[ 是文字括号; ( 开始捕获组,但不是.*,而是在右括号[^]] 之前捕获更安全。为了说明在不必要时使用点的危险,如果您有:&lt;artist&gt;&lt;![CDATA[Years &amp; Years]]&gt;&lt;/artist&gt;&lt;artist2&gt;&lt;![CDATA][blah]]&gt;&lt;/artist2&gt;,您的(.*) 将从第一个“年”到“等等”捕获,而([^]]*) 不会。顺便说一句,在我们的两个正则表达式中,尾随 \s* 是无用的。为避免捕获 ']' 之前的空格,如果 PowerShell 支持零长度断言,请查看它们。 ...\[CDATA\s*\[((?:(?!\s*\]).)*)
    【解决方案3】:

    为了帮助您起步,以下是对 y&y 的建议(尽可能插入空格选择器):

    artist><!\[CDATA\[Years & Years\]\]></artist
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-20
      • 2014-03-02
      • 1970-01-01
      • 2014-09-07
      • 1970-01-01
      • 2013-08-04
      • 1970-01-01
      • 2011-06-07
      相关资源
      最近更新 更多