替换Oracle中的一列电子邮件中的多个字符

时间:2012-08-14 13:35:26

标签: sql oracle email-validation data-cleansing

所以基本上我有一列多封电子邮件,其中一些是无效的,包含不允许的不同字符/回车。

下面是我如何在select语句中查找无效的电子邮件,但我不知道如何单独替换它们,例如,如果发现回车,我知道我会使用替换语句。与任何特殊字符相同。但这会涉及为每种可能的案例编写单独的查询吗?

基本上我要求的是在我的表中迭代替换电子邮件地址中与其中一个案例陈述匹配的任何字符的最有效方法

select /*+  parallel(a,12) full(a) */  a.row_id, a.par_row_id, a.attrib_01,     a.created_by, a.last_upd_by from s_contact_xm a 
where a.type = 'Email' and (a.attrib_01 IS NULL
or a.attrib_01 like '% %'
or a.attrib_01 like '%@%@%'
or a.attrib_01 like '%..%'
or a.attrib_01 like '%;%'
or a.attrib_01 like '%:%'
or attrib_01 not like '%@%'
or a.attrib_01 like '%/%'
or a.attrib_01 like '%\%'
or a.attrib_01 like '%|%'
or a.attrib_01 like '%@.%'
or a.attrib_01 like '%@'
or a.attrib_01 like '%.'
or a.attrib_01 like '%(%'
or a.attrib_01 like '%)%'
or a.attrib_01 like '%<%'
or a.attrib_01 like '%>%'
or a.attrib_01 like '%#%'
or a.attrib_01 like '%"%'
or a.attrib_01 like '%.@%'
or a.attrib_01 like '%..%'
or a.attrib_01 like '.%'
or a.attrib_01 IS NULL
or INSTR(a.attrib_01, CHR(13)) > '0'
or INSTR(a.attrib_01, CHR(10)) > '0') and a.created_by = ‘1-XAAX5P’

2 个答案:

答案 0 :(得分:0)

你会发现很多关于验证电子邮件的链接,这不是复制/粘贴解决方案,也不是涵盖电子邮件的所有情况,只显示方法

我会使用regexp_replace,查找任何非字母数字或其他可接受字符列表(如@或。)

根据您的规则修改此项。它显示了使用奇怪或不可打印的字符清理字符串:

select regexp_replace('A^b\c@de' || chr(9) || 'f.com', '[^[:alnum:]@.]','') from dual;
  

Abc@def.com

在更新声明中:

update my_table
set email = regexp_replace(email, '[^[:alnum:]@.]','');

完整示例(11gr2):

SQL> create table t1
(
email varchar2(100)
)
Table created.
SQL> insert into t1 values ('a^bc@#.com')
1 row created.
SQL> insert into t1 values ('a\*bc' || chr(10) || '.net')
1 row created.
SQL> commit
Commit complete.
SQL> select * from t1

EMAIL                                                                          
--------------------------------------------------------------------------------
a^bc@#.com                                                                     
a\*bc                                                                          
.net                                                                           


2 rows selected.

SQL> update t1 set email = regexp_replace(email, '[^[:alnum:]@.]','')
2 rows updated.

SQL> commit
Commit complete.
SQL> select * from t1

EMAIL                                                                           
--------------------------------------------------------------------------------
abc@.com                                                                       
abc.net                                                                         

2 rows selected.

请注意,这不会强制执行任何严格的电子邮件规则,它只会删除可接受的字符范围之外的字符(您的OP要求的字符)。

答案 1 :(得分:0)

问题是,你有几种不同的潜在错误类别。有些是可以修复的错别字;有些是不可修复的错别字;有些是错的。现在,是否有可能提出一些防弹规则来确定任何给定错误的类别?

也许

例如,您可以将每次出现'%..%'转换为'%。%'。同样,您可以使用null替换回车符。那些是可以解决的错别字。

但如果某人在电子邮件地址中包含",您无法确定他们是否打算输入:您是否认为他们输入2并且没有注意到他们也在按[shift]或者你用null替换它(即删除它)?这不是一个可修复的拼写错误(但你可能会认为猜测已经足够了)。

如果电子邮件地址不包含@,那么它不是有效的电子邮件地址,也无法修复。

所以你可能需要几个单独的UPDATE语句。您将运行一个来翻译您将尝试一对一替换的字符串。这是您想要用null替换的东西的技术,例如那些回车。

translate(attrib_01, '()"'||chr(13), '902')

你需要多次传递来转换多字符串,例如

replace(attrib_01, '..', '.')  

然后你可能想修剪前导或尾随点

trim(both '.' from attrib_01 ) 

最后,您需要报告所有无法修复的地址,例如没有(或几个)结构的值。

您可以使用REGEXP_REPLACE将其中一些规则压缩为更少的步骤。正则表达式将变得非常复杂。使用旧的skool Oracle替换函数可以更容易地使事情正确。我建议你只使用正则表达式,如果你真的需要性能。即使这样,您仍然需要通过数据进行多次传递。


  

“'()”'这是否意味着空值和括号? “

Oracle文档全面,免费且在线。您可以阅读有关REPLACE()的所有信息。那里TRANSLATE()TRIM()

但我会更多地解释一下REPLACE()调用。此函数用第二个字符串中的匹配字符替换第一个字符串中的每个字符。任何缺少匹配的字符都将被丢弃。因此(替换为9)替换为0"替换为2。 (查看QWERTY键盘以了解原因)。 chr(13)(回车)没有匹配,因此被丢弃(或者如果您更愿意用这种方式将其替换为NULL)。


考虑到这一点,您可以在UPDATE set子句中部署CASE语句,以在一次执行中应用不同的REPLACE(),TRIM()和TRANSLATE()调用。这取决于你希望你的代码是多么难以理解:)