Замените ключевые слова в тексте, сравнив его с набором символов - PullRequest
0 голосов
/ 12 октября 2018

В моей таблице sql есть столбец Nvarchar.Я хочу заменить / замаскировать некоторые слова в нем на ***, сравнивая его с набором предопределенных символов.

Это означает, что если мой столбец содержит слова из предопределенного списка слов, то я хочу замаскировать их.Предопределенный список слов составляет около 400 слов.

Образец DDL и DML:

DECLARE @Comments TABLE (id INT, comment VARCHAR(50))
INSERT INTO @Comments VALUES (1, 'Bob is a sales person'), (2, 'Shane is a nice guy')
DECLARE @People TABLE (personname VARCHAR(50))
INSERT INTO @People VALUES ('Bob'), ('Mark'), ('Shane')

Пример данных:

+----+-----------------------+
| id |        comment        |
+----+-----------------------+
|  1 | Bob is a sales person |
|  2 | Shane is a nice guy   |
+----+-----------------------+

Предопределенные слова:

+------------+
| personname |
+------------+
| Bob        |
| Mark       |
| Shane      |
+------------+

ПРИМЕЧАНИЕ:

  • см. Прикрепленные изображения для примеров данных.
  • Я хочу заменить / маскировать на ***, если в столбце комментариев содержится имя человека в предопределенных словах

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Начиная с SQL Server 2017, вы можете использовать STRING_AGG (подробнее здесь ) вместе с STRING_SPLIT, чтобы разбить ваши предложения на слова, заменить имена на ***, а затем объединить обратно отдельные словав предложения:

select co.id, 
      string_agg(case when p.personname is null then c.value else '***' end,' ') as comment
from @Comments co
cross apply string_split(comment,' ') c
left join @People p on p.personname = c.value
group by co.id

Результаты:

enter image description here

Если у вас есть символы, отличные от пробелов между словами, вы можете заменить их пробеламидо разделения:

DECLARE @Comments TABLE (id INT, comment VARCHAR(50))
INSERT INTO @Comments VALUES
  (1, 'Bob (is a sales person)')
, (2, '(Shane:is-a-nice-guy)')
, (3, 'This.is(Mark),he.is-a-nice-guy,too')
DECLARE @People TABLE (personname VARCHAR(50))
INSERT INTO @People VALUES ('Bob'), ('Mark'), ('Shane')

select co.id, 
      trim(string_agg(case when p.personname is null then c.value else '***' end,' ')) as comment
from
(
select id, replace(replace(replace(replace(replace(replace(comment,':',' '),')',' '),'(',' '),',',' '),'.',' '),'-',' ') as comment 
from @Comments
) co
cross apply string_split(comment,' ') c
left join @People p on p.personname = c.value
group by co.id

Теперь с таким типом ввода:

enter image description here

вы получите этот вывод:

enter image description here

0 голосов
/ 12 октября 2018

Что если у вас есть Боб и Бобби?Вы не можете сначала заменить Боба, иначе вы получите *** на.Вот подход, который заменяет строки в обратном порядке длины.Это начало.

Тем не менее, если Боб - бобслей, вы в итоге получите *** - *** санок.

DECLARE @Comments TABLE (id INT, comment VARCHAR(50))
INSERT INTO @Comments VALUES (1, 'Bob is a sales person'), (2, 'Shane is a nice guy')
DECLARE @People TABLE (personname VARCHAR(50))
INSERT INTO @People VALUES ('Bob'), ('Mark'), ('Shane')

DECLARE @curname VARCHAR(50)
DECLARE cur CURSOR FOR   
SELECT personname FROM @people ORDER BY LEN(personname) DESC, personname desc

OPEN cur  

FETCH NEXT FROM cur   
INTO @curname

WHILE @@FETCH_STATUS = 0  
BEGIN       
    UPDATE @Comments SET comment = REPLACE(comment, @curname, REPLICATE('*', LEN(@curname)))

    FETCH NEXT FROM cur   
    INTO @curname
END   
CLOSE cur;  
DEALLOCATE cur;  

Выход:

SELECT * FROM @Comments

id  comment
1   *** is a sales person
2   ***** is a nice guy

Пара быстрых модов:

1) Заменить с учетом регистра:

UPDATE @Comments SET comment = REPLACE(comment COLLATE Latin1_General_CS_AS, @curname, REPLICATE('*', LEN(@curname)))

2) Заменитьтолько первый экземпляр:

UPDATE @Comments SET comment = CASE WHEN CHARINDEX(@curname, comment) > 0   
    THEN STUFF(comment, CHARINDEX(@curname, comment), LEN(@curname), REPLICATE('*', LEN(@curname)))
    ELSE comment
    END  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...