Как стать автором
Обновить

Разбор регулярного выражения, проверяющего простоту чисел

Уровень сложностиПростой
Время на прочтение16 мин
Количество просмотров11K
Всего голосов 47: ↑46 и ↓1+66
Комментарии15

Комментарии 15

Спасибо за статью. Она наконец-то сподвигла меня сесть разобраться с группами в регулярках.

Но я не смог распарсить ваше утверждение "регулярное выражение ^aa(.+)cc(dd)\1$ не соответствует строке aaHELLOccddHELLO, но соответствует строке aaHELLOccddGOODBYE"

Специально пошёл проверить на regex101 именно с этим примером мои результаты не совпали с вашим утверждением. Это у вас ошибка или я ничего не понял?

В оригинале:

This means, that the regular expression ^aa(.+)cc(dd)\1$ does match the sting aaHELLOccddHELLO, but does not match the sting aaHELLOccddGOODBYE

То есть превод вводит в заблуждение.

Спасибо, исправлю.

Вы с переводом разговариваете.

Но перевод то не сам себя создал, его же кто-то создал. Обычно когда в переводе находят ошибки, то делают сноски или добавляют комментарии от автора в которых указано, что тут опечатка или автор оригинала вводит в заблуждение.

Спасибо. Что-то я упустил этот момент.

В оригинале " This means, that the regular expression ^aa(.+)cc(dd)\1$ does match the sting aaHELLOccddHELLO, but does not match the sting aaHELLOccddGOODBYE "

чтобы сделать жадный квантификатор нежадным, перед ним нужно поставить вопросительный знак (?)

Не перед ним, а после него. И в следующем абзаце такая же ошибка.

Да, спасибо, это у автора какая-то путаница. Исправляю.

В какой-то момент, изучая регексы, особенно в языках, где ими очень просто пользоваться (perl, да), начинаешь фантазировать, что можно все задачи со строками решить только регекспами, вплоть до парсинга html!

Но со временем эти фантазии улетучиваются и сначала в регулярках перестаешь применять неочевидные pcre-шные операции, за расшифровкой которых лезешь в man, а потом и вовсе применяешь регуляки для не сложных валидаций, где хватает базового набора, перечисленного в статье.

По-хорошему, при попытке парсинга чего бы то ни было надо натыкаться на товарища Хомского и это даёт довольно простой и быстрый ответ что чем можно распарсить. Окей, не в случае простых чисел :)

Вариант на Perl можно записать чуть проще, используя оператор !~:

sub is_prime {
    return ('1' x $_[0]) !~ m/^.?$|^(..+?)\1+$/;
}

У меня только один вопрос: неужели такое и правда может работать быстрее, чем пройти циклом от 2 до sqrt(N) и просто проверить остаток от деления? Или это для тех редких случаев, когда по каким-то причинам исходные данные представлены в виде строки с унарной записью числа?

Это даже не на порядки медленнее, а невообразимо медленнее. Смысл такого упражнения - "смотри, как я могу!"

Нет, это будет работать медленнее. А на больших числах ещё и жрать неприлично много памяти.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации