REGEXP_REPLACE 替换列表中除特定域之外的电子邮件

Posted

技术标签:

【中文标题】REGEXP_REPLACE 替换列表中除特定域之外的电子邮件【英文标题】:REGEXP_REPLACE to replace emails in a list except a specific domain 【发布时间】:2018-01-04 09:24:19 【问题描述】:

我是正则表达式的新手。我正在尝试从不属于特定域的列表中删除电子邮件。

例如我有以下电子邮件列表:

John@yahoo.co.in , Jacob@gmail.com, Bob@rediff.com,
Lisa@abc.com, sam@gmail.com , rita@yahoo.com

我只需要获取 gmail id:

Jacob@gmail.com, sam@gmail.com

请注意,逗号分隔符前可能有空格。 感谢任何帮助!

【问题讨论】:

使用 like%gmail.com 作为 Select * from Table_name where Email like %gmail.com 修复您的数据模型。不要将列表存储在字符串中。这不是存储列表的 SQLish 方式。 使用 REPLACE_REGEXP 函数,您将定义与要过滤的域匹配的表达式并用空字符串替换它们 【参考方案1】:

这可能是你的开始。

SELECT *
  FROM (    SELECT REGEXP_SUBSTR (str,
                                  '[[:alnum:]\.\+]+@gmail.com',
                                  1,
                                  LEVEL)
                      AS SUBSTR
              FROM (SELECT ' John@yahoo.co.in , Jacob.foo@gmail.com,   Bob@rediff.com,Lisa@abc.com, sam@gmail.com , sam.bar+***@gmail.com, rita@yahoo.com, foobar '
                              AS str
                      FROM DUAL)
        CONNECT BY LEVEL <= LENGTH (REGEXP_REPLACE (str, '[^,]+')) + 1)
 WHERE SUBSTR IS NOT NULL ;

再举几个例子,但电子邮件检查器应遵守各自的 RFC,请查看***以获取有关它们的更多信息https://en.wikipedia.org/wiki/Email_address

来自https://***.com/a/17597049/869069的灵感

【讨论】:

【参考方案2】:

与其抑制与特定域不匹配的电子邮件(在您的示例中为gmail.com),不如尝试仅获取与该域匹配的那些电子邮件:

WITH a1 AS (
    SELECT 'John@yahoo.co.in , Jacob@gmail.com, Bob@rediff.com,Lisa@abc.com, sam@gmail.com , rita@yahoo.com' AS email_list FROM dual
)
SELECT LISTAGG(TRIM(email), ',') WITHIN GROUP ( ORDER BY priority )
  FROM (
    SELECT REGEXP_SUBSTR(email_list, '[^,]+@gmail.com', 1, LEVEL, 'i') AS email
         , LEVEL AS priority
      FROM a1
   CONNECT BY LEVEL <= REGEXP_COUNT(email_list, '[^,]+@gmail.com', 1, 'i')
);

也就是说,Oracle 可能不是最好的工具(您是否将这些电子邮件地址作为列表存储在某处的表格中?如果是这样,那么@GordonLinoff 的评论很恰当 - 如果可以,请修复您的数据模型)。​​

【讨论】:

【参考方案3】:

这是一种使用 CTE 的方法,只是为了解决问题。第一步是制作一个包含已解析列表元素的 CTE“表”。然后从中选择。 CTE 正则表达式处理 NULL 列表元素。

with main_tbl(email) as (
  select ' John@yahoo.co.in , Jacob.foo@gmail.com,   Bob@rediff.com,Lisa@abc.com, sam@gmail.com , sam.bar+***@gmail.com, rita@yahoo.com, foobar '
  from dual
),
email_list(email_addr) as (
  select trim(regexp_substr(email, '(.*?)(,|$)', 1, level, NULL, 1))
  from main_tbl
  connect by level <= regexp_count(email, ',')+1
)
-- select * from email_list;
select LISTAGG(TRIM(email_addr), ', ') WITHIN GROUP ( ORDER BY email_addr )  
from email_list
where lower(email_addr) like '%gmail.com';

【讨论】:

以上是关于REGEXP_REPLACE 替换列表中除特定域之外的电子邮件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 REGEXP_REPLACE 替换特定条件下的重复单词?

替换输入字符串中除第一个字符外的其他字符的实例。

如何替换除-(破折号)以外的特殊字符

Postgresql regexp_replace 替换所有数字

REGEXP_REPLACE 字符串以雪花中的特定子字符串开头和结尾

RegExp_Replace Oracle 中某个单词列表之后的所有内容