【问题标题】:How to identify the words in between a particular pattern using regexp: Oracle?如何使用正则表达式识别特定模式之间的单词:Oracle?
【发布时间】:2020-01-28 02:45:04
【问题描述】:

我有一个文本字段。我需要识别模式<a hrefa> 之间的单词。

此模式可以位于文本的开头/结尾/中间。

with t as (
select '<a href Part of the technical Network Group www.tech.com/sites/ hh a>' as text from dual
union select '<a href www.tech.technical Network a>' as text from dual union
select 'www.tech.tech///technical <a href Network Group a>' as text from dual)
select * from t
WHERE REGEXP_LIKE(text,'(^|\W)<a href\S*','i') 

这给了我正确的前 2 行结果。但我需要检查“组”这个词(不区分大小写)。我们如何检查“组”这个词以及这个词应该在模式中。在这种情况下,应该返回第 1 行和第 3 行。

【问题讨论】:

    标签: sql regex oracle string-matching regexp-like


    【解决方案1】:

    搜索完整的模式,然后在该模式的子字符串中搜索单词Group。如果文本中有多个匹配项,那么您可以使用递归子查询因式分解子句来查找它们:

    Oracle 设置

    CREATE TABLE table_name ( id, text ) AS
    select 1, '<a href Part of the technical Network Group www.tech.com/sites/ hh a>' from dual union all
    select 2, '<a href www.tech.technical Network a>' from dual union all
    select 3, 'www.tech.tech///technical <a href Network Group a>' from dual union all
    select 4, '<a hrefgroup a>' FROM DUAL UNION ALL
    select 5, '<a href groupa>' FROM DUAL UNION ALL
    select 6, '<a href workgroup a>' FROM DUAL UNION ALL
    select 7, '<a href test1 a> Group <a href test2 a>' FROM DUAL;
    

    查询

    WITH positions ( id, text, match, position ) AS (
      SELECT id,
             text,
             REGEXP_SUBSTR(
               text,
               '(^|\W)<a href\s+.*?\s+a>(\W|$)',
               1,
               1,
               'i'
             ),
             REGEXP_INSTR(
               text,
               '(^|\W)<a href\s+.*?\s+a>(\W|$)',
               1,
               1,
               0,
               'i'
             )
      FROM   table_name
    UNION ALL
      SELECT id,
             text,
             REGEXP_SUBSTR(
               text,
               '(^|\W)<a href\s+.*?\s+a>(\W|$)',
               position + 1,
               1,
               'i'
             ),
             REGEXP_INSTR(
               text,
               '(^|\W)<a href\s+.*?\s+a>(\W|$)',
               position + 1,
               1,
               0,
               'i'
             )
      FROM   positions
      WHERE  position > 0
    )
    SELECT id,
           text
    FROM   positions
    WHERE  REGEXP_LIKE( match, '\sGroup\s', 'i' );
    

    输出

    身份证 |文本 -: | :------------------------------------------------ ------------------ 1 | 3 | www.tech.tech///technical

    db小提琴here

    【讨论】:

    • 这行得通。谢谢。有没有办法在 WHERE 条件下检查这个条件?我的意思是作为 REGEXP_LIKE 的一部分。
    【解决方案2】:

    你可以像这样扩展你的正则表达式:&lt;a href.*group.*a&gt;

    Demo on DB Fiddle

    with t as (
        select '<a href Part of the technical Network Group www.tech.com/sites/ hh a>' as text from dual
        union all select '<a href www.tech.technical Network a>' as text from dual
        union all select 'www.tech.tech///technical <a href Network Group a>' as text from dual)
    select * from t
    WHERE REGEXP_LIKE(text,'<a href.*group.*a>','i') 
    
    |正文 | | :------------------------------------------------- ------------------- | | | | www.tech.tech///technical |

    注意:只要您的文本仅包含一个 &lt;a href ... a&gt; 模式(您的示例数据中就是这种情况),这将起作用。


    您可以改进正则表达式以确保它仅匹配单词'group'(而不匹配包含'group' 的其他单词,例如'workgroup''grouped'):

    <a href.*\sgroup\s.*a>
    

    只要&lt;a href 后面总是有一个空格并且a&gt; 之前总是有一个空格,这就可以了。

    Demo on DB Fiddle

    【讨论】:

    • 您可能希望在您的正则表达式中的“组”一词的任一侧放置一个空格,否则如果出现“组”是另一个词(例如“工作组”)的一部分,您会选择这些行.这将产生一组很好的测试数据,甚至可以测试意外的值。
    • 这会选择&lt;a href workgroup a&gt;&lt;a hrefgroup a&gt;&lt;a href groupa&gt;
    • 如果你能有类似&lt;a href test a&gt; group some maths text ... a&gt;b ...的东西,你就不需要两个模式了
    猜你喜欢
    • 2013-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2018-06-23
    • 2021-05-18
    • 1970-01-01
    相关资源
    最近更新 更多