【问题标题】:Regex for newline in XMLXML中换行符的正则表达式
【发布时间】:2014-07-30 16:01:21
【问题描述】:

我正在拼命想办法解决这个问题,但没有运气。我正在尝试在 Postgres 中解析这些 XML 数据:

<map>
  <entry>
    <string>id</string>
    <string>555</string>
  </entry>
  <entry>
    <string>label</string>
    <string>Need This Value</string>
  </entry>
  <entry>
    <string>key</string>
    <string>748</string>
  </entry>
</map>

我试图在&lt;string&gt;label&lt;/string&gt; 之后立即获取string 元素中的值。请注意,我正在使用的 Postgres 版本没有安装 XML (libxml) 函数。

我尝试了很多变体:

substring(xmlStringData from E'&lt;string&gt;label&lt;/string&gt;\\n&lt;string&gt;(.*?)&lt;/string&gt;')

但没有运气。

【问题讨论】:

  • 你为什么不改用xpath()
  • 如原帖中所述,该功能未安装在我正在使用的 Postgres 数据库上,由于它是生产数据库,我无法简单地安装它。
  • 正则表达式?放下它们,你会看到光明。您可以尝试匹配两个捕获 (&lt;string&gt;1&lt;/string&gt;&lt;string&gt;2&lt;/string&gt;),但 XML 可能非常不规则,并且您的正则表达式可能仅适用于定义明确的严格格式。
  • 嗯,你提到了定义明确的严格格式,几乎把我引向了正确的方向
  • the Postgres version I'm working does not have the XML (libxml) function installed. 让我们知道这个秘密怎么样?您的 Postgres 版本是什么

标签: xml regex postgresql postgresql-9.0


【解决方案1】:

xpath() 将是这里的正确工具。 因为,你知道...

当你陷入不幸的境地时,这可以解决问题:

WITH t(x) AS (SELECT '<map>
  <entry>
    <string>id</string>
    <string>555</string>
  </entry>
  <entry>
    <string>label</string>
    <string>Need This Value</string>
  </entry>
  <entry>
    <string>key</string>
    <string>748</string>
  </entry>
</map>'::text
)
SELECT substring(x, '<string>label</string>[\s]*?<string>(.*?)</string>')
FROM  t

返回:

substring
---------------
Need This Value

正则表达式解释:

&lt;string&gt;label&lt;/string&gt; .. 找到位置
[\s].. 空格(包括\n\r
*? .. 这样做“非贪婪”,所以忽略空格直到 ...
&lt;string&gt;.. 下一个字符串元素
(.*?) .. 捕获括号,任何字符,非贪婪
&lt;/string&gt; .. 直到下一次出现结束标记

这是中途可靠的,除非您使用非常规的 XML 格式 - 这就是为什么您应该使用 XML 解析器以 ...

【讨论】:

    【解决方案2】:

    所以我似乎明白了。我只需要考虑换行符后的空格。解决方案是:

    substring(event_data from E'<string>label</string>\\n\\s*?<string>(.*?)</string>')
    

    【讨论】:

      【解决方案3】:

      如果您的&lt;entry&gt; 列表不可变。您可以使用以下正则表达式并在第 4 场比赛中访问捕获组来获取内容。

      <string>(.*?)<\/string>
      

      Working demo

      另一方面,如果您想在第一场比赛中访问,您可以使用以下正则表达式:

      <string>id<\/string>|<string>\d+<\/string>|<string>label<\/string>|<string>(.*?)<\/string>
      

      Working demo

      【讨论】:

      • 看起来 OP 想要立即获取该值,而不是搜索大量匹配项。
      • @skamazin 好吧,OP 没有具体说明,但你可能是对的。我第一次提供了另一种选择。谢谢你让我知道
      猜你喜欢
      • 2022-10-13
      • 2011-06-29
      • 2014-03-10
      • 2012-10-30
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多