0

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

以下是我如何在选择语句中查找无效电子邮件,但我不知道如何单独替换它们,例如,如果找到回车,我知道我会使用替换语句。与任何特殊字符相同。但这将涉及为每个可能的情况编写单独的查询?

基本上,我要求的是最有效的方法来遍历我的表,替换电子邮件地址中与这些案例语句之一匹配的任何字符

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’
4

2 回答 2

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 所要求的)。

于 2012-08-14T15:01:08.783 回答
0

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

也许。

例如,您可以将每次出现的 '%..%' 转换为 '%.%'。同样,您可以将回车替换为 null。这些是可修复的错别字。

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

如果电子邮件地址不包含 a@那么它不是一个有效的电子邮件地址并且没有办法修复它。

因此,您可能需要几个单独的 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 集合子句中部署 CASE 语句,以在一次执行中应用不同的 REPLACE()、TRIM() 和 TRANSLATE() 调用。这取决于你希望你的代码有多难以理解:)

于 2012-08-14T15:25:36.407 回答