(.*)(?:table)?
терпит неудачу с table
(соответствует его) в качестве первой группы (.*)
является жадного точка соответствует шаблону, который захватывает всю строку в группу 1. Регулярное выражение двигателя backtracks и ищет table
в необязательной группе без захвата и соответствует пустой строке в конце строки.
регулярного выражение Хитрость заключается в том, чтобы соответствовать любому тексту, который начинается не с table
до опциональных групп:
^((?:(?!table).)+)(?:table)?$
См the regex demo
Теперь, группа 1 - ((?:(?!table).)+)
- содержит tempered greedy token(?:(?!table).)+
, который соответствует 1 или более символам, отличным от новой строки, которые не запускают последовательность table
. Таким образом, первая группа никогда не будет соответствовать table
.
Анкеры позволяют регулярному выражению соответствовать всей строке.
ПРИМЕЧАНИЕ: Решения без регулярных выражений могут оказаться более эффективными, хотя умеренный токен является довольно ресурсоемким.
Примечание 2: разворачивая закаленную жадную фишку обычно повышает производительность п раз:
^([^t]*(?:t(?!able)[^t]*)*)(?:table)?$
См another demo
Но обычно это выглядит "загадочное", "нечитаемый" и "неосновательный".
Try [ '^ ((?:?! (Таблица)) +.)? (?: Таблица) $'] (https://regex101.com/r/bM8nZ8/1) –
Ничего себе ... не могли бы вы объяснить это? – learningtocode