Апостроф в начале / конце строки поиска, не рассматривается RegEx как часть слова - PullRequest
0 голосов
/ 19 января 2019

Мы запустили словарь и столкнулись с проблемой поиска, который содержит апостроф в начале строки поиска. В английских словах, таких как 'twas , довольно редко, но на языке, с которым мы имеем дело,' считается символом слова и чрезвычайно часто встречается в начале фразы (например, '* * 1004). *), а также в конце слов (например, a ').

Как ни странно, поиски RegEx, похоже, не справляются с этим, если он находится в середине (например, air a 'bhòrd получает все желаемые результаты), но' в начале или конце строки поиска RegEx не рассматривается как часть слова.

Мы убедились, что это является частью спецификации RegEx (только буквенно-цифровые символы и _ обрабатываются как часть слова), но мы задаемся вопросом, возможно ли написать выражение RegEx, которое также обрабатывает апострофы как часть слово?

Вот что мы сейчас получаем:

-- Demonstration on MySQL 5.6.21 Community
Select ('cat''s' REGEXP CONCAT('[[:<:]]', 'cat''s', '[[:>:]]'));
-- returns 1
Select ('''cat''s' REGEXP CONCAT('[[:<:]]' ,'''cat''s' ,'[[:>:]]' ));
-- returns 0
Select ('_cat''s' REGEXP CONCAT('[[:<:]]' ,'_cat''s' ,'[[:>:]]' ));
-- returns 1
Select ('-cat''s' REGEXP CONCAT('[[:<:]]' ,'-cat''s' ,'[[:>:]]' ));
-- returns 0
Select (' cat''s' REGEXP CONCAT('[[:<:]]' ,' cat''s' ,'[[:>:]]' ));
-- returns 0
Select ('cat''' REGEXP CONCAT('[[:<:]]' ,'cat''' ,'[[:>:]]' ));
-- returns 0

Любые предложения приветствуются:)

1 Ответ

0 голосов
/ 19 января 2019

Я думаю, что вы должны предоставить свое собственное определение того, что представляет собой символ слова, вместо того, чтобы полагаться на границы слов по умолчанию ICE ([[:<:]], [[:>:]]). Из документации mysql 5.6 :

Слово - это последовательность символов слова, которой не предшествуют и не следуют символы слова. Символ слова - это буквенно-цифровой символ в классе alnum или знак подчеркивания (_).

Это будет означать: '^|[^[:alnum:]_]'

^             -- the beginning of the string
|             -- OR
[^            -- any character OTHER than
    [:alnum:]     -- an alphanumeric character
    _             -- an underscore
]

И конец строки ICE будет: '[^[:alnum:]_]|$', где $ представляет конец строки.

Вы можете просто изменить это, чтобы добавить одинарную кавычку в класс символов, например:

  • начало: '^|[^[:alnum:]_'']'
  • конец: '[^[:alnum:]_'']|$'

Вот ваше регулярное выражение:

SELECT (val REGEXP CONCAT('(^|[^[:alnum:]_''])', 'cat''s', '([^[:alnum:]_'']|$)'));

См. Демо на dbfiddle

Схема (MySQL v5.6)


Запрос № 1

Select ('cat''s'
    REGEXP CONCAT('(^|[^[:alnum:]_''])', 'cat''s', '([^[:alnum:]_'']|$)')) res;
| res |
| --- |
| 1   |

Запрос № 2

Select ('''cat''s' 
    REGEXP CONCAT('(^|[^[:alnum:]_''])', '''cat''s', '([^[:alnum:]_'']|$)' )) res;
| res |
| --- |
| 1   |

Запрос № 3

Select ('_cat''s'
    REGEXP CONCAT('(^|[^[:alnum:]_''])', '_cat''s' , '([^[:alnum:]_'']|$)' )) res;
| res |
| --- |
| 1   |

Запрос № 4

Select ('-cat''s'  
    REGEXP CONCAT('(^|[^[:alnum:]_''])', '-cat''s' , '([^[:alnum:]_'']|$)' )) res;
| res |
| --- |
| 1   |

Запрос № 5

Select (' cat''s' 
    REGEXP CONCAT('(^|[^[:alnum:]_''])', ' cat''s' , '([^[:alnum:]_'']|$)' )) res;
| res |
| --- |
| 1   |

Запрос № 6

Select ('cat'''
    REGEXP CONCAT('(^|[^[:alnum:]_''])', 'cat''' , '([^[:alnum:]_'']|$)' )) res;
| res |
| --- |
| 1   |

...