REGEX для поиска слов, содержащих перестановки букв, причем одна буква обязательна, а НЕ любая другая - PullRequest
0 голосов
/ 23 сентября 2019

У нас есть таблица mysql со столбцом, содержащим буквенно-цифровой текст.У нас есть уникальный случай использования, когда нам нужно найти каждую строку в таблице, где в этом столбце есть текст, содержащий:

  • Одна буква точно, скажем S
  • Плюс одна или несколькоиз нескольких других букв, скажем, T, A, C, N (буквы могут быть в порядке и повторяться столько раз)
  • НЕ содержат никаких других букв, кроме S и T, A,C, N

Как таковые, они будут в порядке:

SCAN
SCATTCC
NCAS 
NTTAAS

Это не будет в порядке:

CATI     (does not contain S, and contains I which is outside of S, T, C, A, N) 
SCANNF   (contains F which is outside of S, T, C, A, N) 
NCASO    (contains O which is outside of S, T, C, A, N) 
..

Мы пробовали что-то подобное, ноэто не работает:

[tacn]*[s]+(?![^stacn])+

Ответы [ 3 ]

2 голосов
/ 23 сентября 2019

Предполагается, что s может появляться несколько раз, как и другие разрешенные символы.Требования явно не исключают такую ​​возможность, хотя примеры не включают такой пример.Я не понимаю, что «одна буква наверняка» означает «появляется только один раз».

^(s+[tacn][stacn]*|[tacn]+s[stacn]*)$
2 голосов
/ 23 сентября 2019

MySQL 8.0.4 +

Начиная с MySQL 8.0.4, Поддержка регулярных выражений MySQL изменена на библиотеку ICU и поддерживаются запросы на просмотр.Для этих версий это регулярное выражение будет соответствовать вашим требованиям:

'^(?=.*s)(?=.*[acnt])(?!.*[^acnst])'

Используется 3 вида:

  1. (?=.*s) утверждает, что в строке есть S;
  2. (?=.*[acnt]) утверждает, что в строке есть хотя бы один из [ACNT];
  3. (?!.*[^acnst]) утверждает, что в строке нет символов, отличных от [ACNST].

Демонстрация на dbfiddle

MySQL до 8.0.4

Это регулярное выражение даст вам нужные результаты:

^[tacn]*(s[cant]|[tacn]s)[cant]*$

Он ищет либо

  • , либо S, перед которым стоит ноль или более [TACN], а затем один или несколько из [TACN];или
  • и S, перед которым стоит один или несколько из [TACN], а затем ноль или более из [TACN]

Запрос:

SELECT str, 
       str REGEXP '^[tacn]*(s[cant]|[tacn]s)[cant]*$' AS `match`
FROM test

Вывод:

str     match
SCAN    1
SCATTCC 1
NCAS    1
NTTAAS  1
CATI    0
SCANNF  0
NCASO   0
CANT    0
S       0
SS      0
TS      1
SC      1
STS     0

Демонстрация по dbfiddle

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

^[stacn]*(s[cant]|[tacn]s)[scant]*$

Это изменяет результат для STS на 1, оставляя результат для SS как 0, поскольку он не содержит символа, отличного от S.

Демонстрация на dbfiddle

0 голосов
/ 23 сентября 2019

Используйте это регулярное выражение для сопоставления с образцом:

pattern = "^(S+[TACN]+S*[TACN]*)+$|^(S*[TACN]+S+[TACN]*)+$"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...