Поскольку заранее определенный класс символов пунктуации не работает для конца строки, вместо него используется собственный класс символов.Оставляя точку намеренно.Добавление в одиночную кавычку отдельно (поскольку экранирование не сработало, и в этом случае может быть сложно найти правильный символ для оператора q ).Добавление закрывающей квадратной скобки само по себе, так как Oracle, кажется, не справляется с этим правильно при выходе из него.Наконец, добавление завершающих последовательных точек в явном виде:
WITH T (id, col) AS (
SELECT 1, 'GEORGE & SON ' FROM DUAL UNION ALL
SELECT 2, '-GEORGE & SON' FROM DUAL UNION ALL
SELECT 3, '&GEORGE & SON' FROM DUAL UNION ALL
SELECT 4, 'GEORGE & SON..' FROM DUAL UNION ALL
SELECT 5, 'GEORGE & SON.' FROM DUAL UNION ALL
SELECT 6, '-GEORGE & SON S.A.' FROM DUAL UNION ALL
SELECT 7, 'GEORGE & SON!' FROM DUAL UNION ALL
SELECT 8, 'GEORGE & SON"' FROM DUAL UNION ALL
SELECT 9, 'GEORGE & SON#' FROM DUAL UNION ALL
SELECT 10, 'GEORGE & SON$' FROM DUAL UNION ALL
SELECT 11, 'GEORGE & SON%' FROM DUAL UNION ALL
SELECT 12, 'GEORGE & SON&' FROM DUAL UNION ALL
SELECT 13, 'GEORGE & SON(' FROM DUAL UNION ALL
SELECT 14, 'GEORGE & SON)' FROM DUAL UNION ALL
SELECT 15, 'GEORGE & SON*' FROM DUAL UNION ALL
SELECT 16, 'GEORGE & SON+' FROM DUAL UNION ALL
SELECT 17, 'GEORGE & SON,' FROM DUAL UNION ALL
SELECT 18, 'GEORGE & SON\' FROM DUAL UNION ALL
SELECT 19, 'GEORGE & SON-' FROM DUAL UNION ALL
SELECT 20, 'GEORGE & SON\' FROM DUAL UNION ALL
SELECT 21, 'GEORGE & SON/' FROM DUAL UNION ALL
SELECT 22, 'GEORGE & SON:' FROM DUAL UNION ALL
SELECT 23, 'GEORGE & SON;' FROM DUAL UNION ALL
SELECT 24, 'GEORGE & SON<' FROM DUAL UNION ALL
SELECT 25, 'GEORGE & SON=' FROM DUAL UNION ALL
SELECT 26, 'GEORGE & SON>' FROM DUAL UNION ALL
SELECT 27, 'GEORGE & SON?' FROM DUAL UNION ALL
SELECT 28, 'GEORGE & SON@' FROM DUAL UNION ALL
SELECT 29, 'GEORGE & SON[' FROM DUAL UNION ALL
SELECT 30, 'GEORGE & SON^' FROM DUAL UNION ALL
SELECT 31, 'GEORGE & SON_' FROM DUAL UNION ALL
SELECT 32, 'GEORGE & SON`' FROM DUAL UNION ALL
SELECT 33, 'GEORGE & SON{' FROM DUAL UNION ALL
SELECT 34, 'GEORGE & SON|' FROM DUAL UNION ALL
SELECT 35, 'GEORGE & SON}' FROM DUAL UNION ALL
SELECT 36, 'GEORGE & SON~' FROM DUAL UNION ALL
SELECT 37, 'GEORGE & SON''' FROM DUAL UNION ALL
SELECT 38, 'GEORGE & SON]' FROM DUAL)
SELECT
* FROM T
WHERE REGEXP_LIKE(col, '(^[[:punct:]]|[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']$)|]$|\.\.$|(^[[:space:]]|[[:space:]]$)')
ORDER BY id
;
Обновленные требования
Знаки пунктуации с последующей точкой
Добавление дополнительной точки в набор специальных символов;переходя от
'[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']$'
к
'[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']\.?$'
как в
WITH T (id, col) AS (
SELECT 40, 'GEORGE & SON^.'FROM DUAL UNION ALL
SELECT 41, 'GEORGE & SON_.'FROM DUAL UNION ALL
SELECT 42, 'GEORGE & SON`.'FROM DUAL UNION ALL
SELECT 43, 'GEORGE & SON{.'FROM DUAL UNION ALL
SELECT 44, 'GEORGE & SON|.'FROM DUAL UNION ALL
SELECT 45, 'GEORGE & SON}.'FROM DUAL UNION ALL
SELECT 46, 'GEORGE & SON~.'FROM DUAL UNION ALL
SELECT 47, 'GEORGE & SON''.'FROM DUAL UNION ALL
SELECT 48, 'GEORGE & SON].'FROM DUAL)
SELECT
* FROM T
WHERE REGEXP_LIKE(col, '([-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']\.?$)|]\.?$')
ORDER BY id
;
Повторение (комбинаций) пробелов и специальных символов в строке
Первоначально запрашивались только начальные и конечные вхождения…; -)
Последовательности из двух или более символов пробела / пунктуации перехватываются
[[:space:][:punct:]]{2,}
Если вы хотите это явно внутри строк,only - окружить их символами слова:
\w[[:space:][:punct:]]{2,}\w
Начальные / завершающие последовательные пробелы уже сопоставлены, когда найден один - нет необходимости беспокоиться о них явно.
Что дает:
WITH T (id, col) AS (
SELECT 50, 'GEORGE & SON ' FROM DUAL UNION ALL
SELECT 51, 'GEORGE & SON ' FROM DUAL UNION ALL
SELECT 52, ' GEORGE & SON' FROM DUAL UNION ALL
SELECT 53, ' GEORGE & SON' FROM DUAL UNION ALL
SELECT 54, 'GEORGE & SON' FROM DUAL UNION ALL
SELECT 55, 'GEORGE & SON S.A.' FROM DUAL UNION ALL
SELECT 56, 'GEORGE & SON S.A.' FROM DUAL UNION ALL
SELECT 60, ' GEORGE and SON' FROM DUAL UNION ALL
SELECT 61, ' ,GEORGE and SON' FROM DUAL UNION ALL
SELECT 62, ', GEORGE and SON' FROM DUAL UNION ALL
SELECT 63, 'GEORGE -- SON' FROM DUAL UNION ALL
SELECT 64, 'GEORGE --SON' FROM DUAL UNION ALL
SELECT 65, 'GEORGE & SON' FROM DUAL UNION ALL
SELECT 66, 'GEORGE + SON' FROM DUAL UNION ALL
SELECT 67, 'GEORGE and , SON' FROM DUAL UNION ALL
SELECT 68, 'GEORGE and , SON' FROM DUAL UNION ALL
SELECT 69, 'GEORGE and SON ,' FROM DUAL UNION ALL
SELECT 70, 'GEORGE and SON. ' FROM DUAL UNION ALL
SELECT 71, 'GEORGE and+-SON' FROM DUAL)
SELECT
* FROM T
-- WHERE REGEXP_LIKE(col, '(^[[:punct:]]|[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']\.?$)|]$|\.\.$|(^[[:space:]]|[[:space:]]$)|[[:space:][:punct:]]{2,}')
WHERE REGEXP_LIKE(col, '(^[[:punct:]]|[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']\.?$)|]$|\.\.$|(^[[:space:]]|[[:space:]]$)|\w[[:space:][:punct:]]{2,}\w')
ORDER BY id
;
Но это даст ложные срабатывания, наиболее заметно GEORGE & SON .Этого можно в некоторой степени избежать, заменив [: punct:] менее инклюзивным набором.(Окончательный) выбор будет зависеть от того, являются ли ложные отрицания или ложные срабатывания более значимыми.
См. Это в действии:
Поймать произвольные последовательности знаков пунктуации и пробела - но допускается одиночные буквы, за которыми следуют одна точка и один пробел
Как упоминалось ранее, ложные срабатывания должны быть сбалансированы с ложными отрицаниями.Так или другой.Тем не менее, сейчас, вероятно, самое время подумать о том, чтобы разбить общую проблему на более мелкие и заняться ими индивидуально.Даже если GEORGE и P. SON вполне приемлемы, вы, вероятно, захотите просмотреть, например, -GEORGE и P. SON .Итак, давайте сосредоточимся на последовательностях случайных символов в середине строки - даже вспоминая ** и ** ранее и допуская перечисления (и, следовательно, запятые):
WHERE
REGEXP_LIKE(col, '\w[[:space:][:punct:]]{2,}\w')
AND
NOT REGEXP_LIKE(col, ' [[:upper:]]\. \w')
AND
NOT INSTR(col, ', ') > 0
AND
NOT INSTR(col, ' & ') > 0
Возможно, за которыми следует
WHERE
REGEXP_LIKE(col, '\w[[:space:][:punct:]]{2,}\w')
AND
(REGEXP_LIKE(col, ' [[:upper:]]\. \w')
OR
INSTR(col, ', ') > 0
OR
INSTR(col, ' & ') > 0
)
, чтобы найти, например, GEORGE и SON между многими действительными.INSTR
может быть быстрее, чем REGEX - в зависимости от общих обстоятельств ...
Еще несколько слов о механике
(i) [[: punct:] [: space:]] по существу объединяет [[: punct:]] и [[: space:]] в один класс символов.Что касается выбора из этого класса, то порядок не имеет значения.
(ii)
[-!"#$%&()*+,\/:;<=>?@[^_`{|}~' || '''' || ']
равно
[-!"#$%&()*+,\/:;<=>?@[^_`{|}~]
с добавлением одной цитаты,Если бы это было выполнено напрямую, Oracle рассмотрел бы одинарную кавычку для завершения значения параметра.А экранирование одинарной кавычки с обратной косой чертой не сработало ... Так что, по сути, это то, что было названо выше «Добавление в одиночную кавычку отдельно».
Пожалуйста, прокомментируйте, если и как это требует корректировки / более подробно.