Sql server SQL Server:用示例文本替换电子邮件,但保留结构

Sql server SQL Server:用示例文本替换电子邮件,但保留结构,sql-server,regex,tsql,Sql Server,Regex,Tsql,对于SQL Server 2005实例,使用多封电子邮件查找/替换列的最佳方法是什么 <JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com ..... 并将其替换为 <TestMail@yRandMail.com>; TestMail@RandMail.com; TestMail@RandMail.com ..... 出于测试目的,我可以想出一些在C中实现这一点的方法,但我想知道是否

对于SQL Server 2005实例,使用多封电子邮件查找/替换列的最佳方法是什么

<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com .....
并将其替换为

<TestMail@yRandMail.com>; TestMail@RandMail.com; TestMail@RandMail.com .....
出于测试目的,我可以想出一些在C中实现这一点的方法,但我想知道是否有一种在SQL Server中实现这一点的方法,也许是使用正则表达式?我想尽可能地保持这种随机的奇怪,有些电子邮件有括号,有些结尾有分号等等


谢谢你的几点建议:

一种方法可能是:

查找@符号的索引 替换之前的部件,直到前一个空格或其他字符-可能是集合[],;使用您的电子邮件ID 替换它后面的部分,直到域中出现下一个空格或其他字符 使用列中的下一个@符号重复此操作 如果您碰巧替换了友好名称的一部分而不是电子邮件 不经意间,它不应该很重要

使用CHARINDEX查找字符串中@符号的下一个索引。 使用PATINDEX查找特定模式的索引,例如。 空格或其他分隔符。这可能更容易理解 将字符串按节或空格分开处理 整个事情一下子就发生了

编写正则表达式并设置SQLCLR函数来进行替换也可能更容易

如果更换电子邮件地址的原因是为了避免发送 通过向他们发送电子邮件,您可以在 应用设置标志后,将电子邮件地址替换为 开发人员定义的地址或日志,但忽略电子邮件发送


在这里,您可以通过函数中的cte来完成它

create function dbo.FixupEmails(@s varchar(8000))
returns table
as
return (
      WITH splitter_cte AS (
      SELECT CHARINDEX(';', @s) as pos, 0 as lastPos, 1 as cte_level
      UNION ALL
      SELECT CHARINDEX(';', @s, pos + 1), pos, cte_level + 1 as cte_level
      FROM splitter_cte
      WHERE pos > 0
      ), each_email_cte AS(
      select replace(replace(replace(OneEmail, '>', ''), '<', ''), ' ', '') as OneEmail, cte_level
        from (select SUBSTRING(@s, lastPos + 1,
                         case when pos = 0 then 80000 else pos - lastPos -1 end) as OneEmail,
                         cte_level
                from splitter_cte) as t
      ), each_half_cte AS (
        select OneEmail, CHARINDEX('@', OneEmail) as atPos, cte_level
        from each_email_cte
        where len(OneEmail) > 6  -- 6 from x@x.co (I think that 6 would be the minimum valid email length)
      ), new_email_cte as
      (
        select cte1.OneEmail, Replace(@s, cte1.OneEmail, 'TestMail@RandMail.com') as New, cte1.cte_level --, 1 as level
        from each_half_cte cte1
        where cte1.cte_level = 1

        UNION ALL

        select cte2.OneEmail, Replace(necte.New, cte2.OneEmail, 'TestMail@RandMail.com') as New, cte2.cte_level--, 1 as level
        from new_email_cte as necte
        inner join each_half_cte as cte2 on cte2.cte_level = necte.cte_level + 1


      )
      select New
      from new_email_cte
      where cte_level = (select max(cte_level) from new_email_cte)
)
go

set nocount on;

declare @emailString varchar(2048)
set @emailString = '<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com ';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString);




set @emailString = '<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com;';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString);


set @emailString = '<JimmyTheBoot@yahoo.com>';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString)
OPTION(MAXRECURSION 0);
-- include MAXRECURSION as shown above if you have more than 100 email addresses in the field.



set @emailString = '<bill@whatever.co.uk>; John@TestMail.tv;';
select @emailString as Original;
SELECT *
  FROM dbo.FixupEmails(@emailString)
它有点长,但这里是输出

Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com; comfarmer@yahoo.com 

New
-----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com; TestMail@RandMail.com 




Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>; JohnBlaze@TestMail.com;

New
----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com;





Original
----------------------------------------------------------------
<JimmyTheBoot@yahoo.com>

New
----------------------------------------------------------------
<TestMail@RandMail.com>





Original
----------------------------------------------------------------
<bill@whatever.co.uk>; John@TestMail.tv;

New
----------------------------------------------------------------
<TestMail@RandMail.com>; TestMail@RandMail.com;

这很有趣。我认为所提供的函数可以满足您的要求。

我希望您使用c代码来实现这一点。但是你可以在你的陈述中使用LIKE,也许…@F.Muller,我知道它会是什么样子的s@it ... 但这只是为了生成测试数据,我觉得如果我不得不再次这样做,那么在SSMS中运行它会比在VS中运行更方便,不是吗?@bumble\u bee\u tuna no;如果您在完全不涉及数据库的情况下生成测试数据,如果您使用IoC,或者甚至只是使用一个简单的存储库模式,使用一个测试存储库生成测试数据,而不涉及数据库,那么这将更容易。“你试图把这样的事情复杂化,这比你想象的要多得多。”AndrewBarber我实际上用样本数据模拟了一下,然而,我正在编写的归档应用程序依赖于一个预先存在的数据存储,它具有非常特殊的数据分布,例如500-1000个字符的To_Addr电子邮件字段,这将影响UI的执行方式。我无法对现场数据进行测试,因为它很敏感,所以我需要生成样本数据,以便对古怪的预先存在的数据进行密切建模。此外,格式中的一些不规则之处将影响我处理数据的方式。但是,作为一般规则,我同意使用随机样本数据要容易得多。@bumble_bee_tuna如果您的问题如您所述,我建议使用工具混淆数据进行测试,同时保持不规则性完好无损。您所做的基本问题是,您正在插入更多仅用于测试的应用程序代码。一旦代码被删除,您必须再次进行测试,以确保这些代码仍然有效。