MS SQL Server-替换名称,同时避免使用包含名称的单词



这是我第一次在Stack Overflow上发帖,所以如果我能做得更好或提供更多信息,请告诉我。

我已经为这个问题工作了几天了。我有一张桌子,上面有员工对公司的评价。他们中的一些人可能指的是公司中的特定员工。出于人力资源方面的原因,我们希望将任何出现的员工姓名替换为单词"employee"。我们不考虑拼写错误。

我想要的结果的一个例子是:

Input: 'I dislike dijon mustard. My boss Jon sucks.'
Name to search for: 'Jon'
Output: 'I dislike dijon mustard. My boss employee sucks.'

另一个例子:

Input: 'Aggregating data is boring. Greg is the worst person ever.'
Name to search for: 'Greg'
Output: 'Aggregating data is boring. employee is the worst person ever.'


我想在评论中搜索员工姓名的出现情况,但如果两端都没有其他字母或数字,则仅。名称两端带有空格或标点符号的出现应该被替换。

到目前为止,我已经尝试了以下线程中的建议:

在SQL Server中如何在不替换子字符串的情况下替换句子中的特定单词插入-插入-插入

这产生了以下

update c
set c.Comment = rtrim(ltrim(Replace(replace(' ' + c.Comment + ' ',' ' + en.FirstName + ' ', 'employee'), ' ' + en.FirstName + ' ', 'employee')))
from AnswerComment c
join #EmployeeNames en on en.SurveyId = c.SurveyId
and c.Comment like '%' + en.FirstName + '%'

然而,我得到了这样的结果:

Input: 'I hate bob.'
Name to search for: 'Bob'
Output: 'I hate bob.'

Input: 'Jon sucks'
Name to search for: 'Jon'
Output: 'employeesucks'


一位同事查看了这个线程使用ms-sql-server替换整个单词;替换";

并根据它给了我以下信息:

DECLARE @token VARCHAR(10) = 'bob';
DECLARE @replaceToken VARCHAR(10) = 'employee';
DECLARE @paddedToken VARCHAR(10) = ' ' + @token + ' ';
DECLARE @paddedReplaceToken VARCHAR(10) = ' ' + @replaceToken + ' ';
;WITH Step1 AS (
SELECT CommentorId
, QuestionId
, Comment
, REPLACE(Comment, @paddedToken, @paddedReplaceToken) AS [Value]
FROM AnswerComment
WHERE SurveyId = 90492
AND Comment LIKE '%' + @token + '%'
), Step2 AS (
SELECT CommentorId
, QuestionId
, Comment
, REPLACE([Value], @paddedToken, @paddedReplaceToken) AS [Value]
FROM Step1
), Step3 AS (
SELECT CommentorId
, QuestionId
, Comment
, IIF(CHARINDEX(LTRIM(@paddedToken), [Value]) = 1, STUFF([Value], 1, LEN(TRIM(@paddedToken)), TRIM(@paddedReplaceToken)), [Value]) AS [Value]
FROM Step2
)
SELECT CommentorId
, QuestionId
, Comment
, IIF(CHARINDEX(REVERSE(RTRIM(@paddedToken)), REVERSE([Value])) = 1, 
REVERSE(STUFF(REVERSE([Value]), CHARINDEX(REVERSE(RTRIM(@paddedToken)), REVERSE([Value])), LEN(RTRIM(@paddedToken)), REVERSE(RTRIM(@paddedReplaceToken)))), 
[Value])
FROM Step3;

但我不知道该如何实现。

另一个我再也找不到的线程建议使用%[^a-z0-9A-Z]%进行搜索,如下所示:

update c
set c.Comment = REPLACE(c.Comment, en.FirstName, 'employee')
from AnswerComment c
join #EmployeeNames en on en.SurveyId = c.SurveyId
and c.Comment like '%' + en.FirstName + '%'
and c.Comment not like '%[^a-z0-9A-Z]%' + en.FirstName + '%[^a-z0-9A-Z]%'
select @@ROWCOUNT [first names replaced]

这对我不起作用。它会替换出现的员工姓名,即使它们是一个较大单词的一部分,比如这个例子:

Input: 'I dislike dijon mustard.'
Name to search for: 'Jon'
Output: 'I dislike diemployee mustard.'


在这一点上,我似乎不可能做到这一点。我实现这些的方式有什么问题吗,或者我明显缺少什么?

这里有一个方法,它使用STUFF和PATINDEX的组合。

它只会替换注释中第一个出现的名称
因此,它可能需要多次执行,直到没有更新为止。

UPDATE c
SET c.Comment = STUFF(c.Comment, PATINDEX('%[^a-z0-9]'+en.FirstName+'[^a-z0-9]%', '/'+c.Comment+'/'), len(en.FirstName), 'employee')
FROM AnswerComment c
JOIN #EmployeeNames en ON en.SurveyId = c.SurveyId
WHERE '/'+c.Comment+'/' LIKE '%[^a-z0-9]'+en.FirstName+'[^a-z0-9]%';

这样的东西似乎起作用了。

declare @charsTable table (notallowed char(1))
insert into @charsTable (notallowed) values (',')
insert into @charsTable (notallowed) values ('.')
insert into @charsTable (notallowed) values (' ')
declare @input nvarchar(max) = 'Aggregating data is boring. Greg is the worst person ever.'
declare @name nvarchar(50) = 'Greg'
--declare @input nvarchar(max) =  'I dislike dijon mustard. You know who sucks? My boss Jon.'
--declare @name nvarchar(50) = 'Jon'
select case when @name + notallowed = value or notallowed + @name = value or notallowed + @name = value then replace(value, @name, 'employee') else value end 'data()'  from string_split(@input, ' ')
left join @charsTable on @name + notallowed = value or notallowed + @name = value or notallowed + @name + notallowed = value
for xml path('')

结果:

聚合数据很无聊。员工是有史以来最糟糕的人。

我不喜欢第戎芥末。你知道谁很差劲吗?我老板的雇员。

最新更新