如何使用正则表达式识别特定模式之间的单词:Oracle?

Posted

技术标签:

【中文标题】如何使用正则表达式识别特定模式之间的单词:Oracle?【英文标题】:How to identify the words in between a particular pattern using regexp: 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 行。

【问题讨论】:

【参考方案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 ...的东西,你就不需要两个模式了

以上是关于如何使用正则表达式识别特定模式之间的单词:Oracle?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式匹配不以某些字符开头或结尾的单词?

构建正则表达式模式以适应所有这些单词

正则表达式模式匹配第一个和最后一个标记之间的单词,第一个单词是常量

如何使用正则表达式识别特定行? C#

如何使用正则表达式匹配nuxtjs,vue中路由中的特定单词?

使用正则表达式获取用换行符分隔的单词之间的文本