【问题标题】:Substring using Oracle SQL regex使用 Oracle SQL 正则表达式的子字符串
【发布时间】:2017-06-15 06:53:43
【问题描述】:

我创建了一个正则表达式来捕获我需要的字符串。 当我在 rubular.com 等网站上测试正则表达式时,一切正常,但是当我将相同的正则表达式放入 REGEXP_SUBSTR 函数时,它就不起作用了。

这里有 2 个 SQL 示例(一个是英文文本,另一个是 Kristaps Porzingis 的语言):

SELECT regexp_substr('<ul data-error-code="REOPENED" data-unique-error-code="REOPENED"><li class="b">This is the text I would like to substr! <p class="tutorial" href="#">Other random text that I do not need</li></ul>'
                    ,'<li class="b">([\wāēīšžģņļčķū:!,\b\s]+)<') 
  FROM dual;

SELECT regexp_substr('<ul data-error-code="REOPENED" data-unique-error-code="REOPENED"><li class="b">Šī ir valoda, ko lielākā daļa no jums nesaprot! <p class="tutorial" href="#">Other random text that I do not need</li></ul>'
                    ,'<li class="b">([\wāēīšžģņļčķū:!,\b\s]+)<') 
  FROM dual;

我正在尝试在 &lt;li class="b"&gt; 和下一个 html 标记之间选择文本,在本例中为 &lt;p class="tutorial"&gt;

关于我做错了什么有什么建议吗?

【问题讨论】:

    标签: sql regex oracle regexp-substr


    【解决方案1】:

    不建议使用正则表达式解析 HTML,您最好获取字符串并使用能够方便地解析 HTML 的语言对其进行解析。

    如果您手头只有 Oracle DBMS,对于一次性工作,您可以考虑使用以下regexp_substr

    SELECT regexp_substr('<ul><li class="b">Šī ir valoda, ko lielākā daļa no jums nesaprot! <p>Not needed</li></ul>',
          '<li\s+class="b">([^<]+)', 1, 1, NULL, 1) as RESULT from dual
    

    REXTESTER demo

    这里,

    • &lt;li\s+class="b"&gt; - 匹配 &lt;li、1+ 个空格、class="b"&gt;literal 子字符串
    • ([^&lt;]+) - 捕获到第 1 组的一个或多个字符,而不是 &lt;

    最后一个 1 参数允许您访问此组 1 的内容。

    【讨论】:

    • 谢谢。不幸的是,对于这份工作,我只有 Oracle DBMS。我完全同意您的观点,必须使用其他更合适的语言来使用正则表达式解析 HTML。
    • @Alex FYI,根据版本,Oracle DBMS 内置了处理 XML 的方法。例如EXTRACT,它允许您使用 xpath。但是,是的,HTML 并不完全是 XML。
    【解决方案2】:

    您可以简化该正则表达式。
    不要查找特定字符,而是查找不是&lt;&gt; 的字符

    例如:

    SELECT regexp_substr('<ul><li class="b">Šī ir valoda, ko lielākā daļa no jums nesaprot! <p>Not needed</li></ul>'
                        ,'<li class="b">([^<>]+)',1,1,'i',1) as b_class
    FROM dual
    

    其中[^&lt;&gt;] 匹配任何不是&lt;&gt; 的字符

    或者你可以懒惰地匹配字符直到第一个&lt;

    SELECT regexp_substr('<ul><li class="b">Šī ir valoda, ko lielākā daļa no jums nesaprot! <p>Not needed</li></ul>'
                        ,'<li class="b">(.*?)<',1,1,'ni',1) as b_class
    FROM dual
    

    .*? 将尝试使用字符直到第一个 &lt;
    通过添加match parametern,如果标签后面有多行文本,它也会匹配。

    'n' 允许使用句点 (.),它是匹配任意字符的字符, 匹配换行符。如果省略此参数,则周期 与换行符不匹配。

    【讨论】:

      【解决方案3】:

      我会使用 Instr 搜索第一个 html 标记的位置,并在该位置之后执行一个子字符串来获取文本的尾部。下一步是在这个尾部搜索 '

      有点像

      select substring(mytext, 1, instr(mytext, '<')) from 
      (
       select substring(text, instr(text, '<li class="b">') + 
       length('<li class="b">') +1) as mytext from table
      )
      

      【讨论】:

        猜你喜欢
        • 2019-04-17
        • 2021-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多