LINUX.ORG.RU

Упростить регулярное выражение

 , ,


0

1

Привет, ЛОР!

Есть регулярное выражение:

4.13.0-(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21)-.*

Каким образом можно заменить это на диапазон с 1 по 21 таким образом, чтобы регулярное выражение осталось читабельным?

Deleted

Это самое простое. Ты хочешь укоротить. А это не имеет смысла. Ни практического, ни эстетического.

На крайняк

 
$range = join '|', 1..21;

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

anonymous ()

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

anonymous ()
Ответ на: комментарий от anonymous

Не надо переходить на следующий уровень абстракции. Иначе ТС познает, что можно генерировать регекспы из человекочитаемой строки, а там недалеко до парсер-генераторов с семантикой, собственные человекочитаемые дсл… :)

anonymous ()
Ответ на: комментарий от anonymous

там недалеко до парсер-генераторов с семантикой, собственные человекочитаемые дсл… :)

Ну, врядли для его задачи это нужно. Я писал както парсер для микротиковских выхлопов, и мне хватило базового уровня с мешаниной из императивщины.

Но замечу, что тот же Демьян Конвей залез в регекспы перла на самом перле и сделал им дебаггер. Гибкость языка и уровень ниндзя в его владении. Моё восхищение.

anonymous ()

Каким образом можно заменить это на диапазон с 1 по 21

Какой, сцуко, гусь распознаёт диапазоны чисел с помощью регулярок?

Распарсь int и напиши нормальное условие.

anonymous ()
Ответ на: комментарий от anonymous

Вот этим: https://www.regular-expressions.info/brackets.html

+ atoi и if как анонимус повыше советовал. Пользователям его регулярки править вообще нинужно. Да и сама регулярка превращается из 4.13.0-(1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21)-.* (блджад, что за точки в начале?) в 4\.13\.0-([0-9]+)-.*

anonymous ()
Ответ на: комментарий от anonymous

никаких atoi в pcre,

Потому что atoi не из регулярных выражений. Это перевод строки в integer в языке си.

http://man7.org/linux/man-pages/man3/atoi.3.html

import re

text = '4.13.0-20-qwerty'
sub_text = re.match('4\.13\.0-([0-9]+)-.*', text).group(1)
number = int(sub_text)

if 1 <= number <= 21:
    print("OK")
else:
    print("invalid")

anonymous ()

Ну хотя бы 4\.13\.0-([1-9]|1[0-9]|2[01])-.* (не забываем экранировать точки).

А вообще правильнее преобразовать в кортеж/массов чисел и сравнивать напрямую. На питоне это будет как-то так:

[4, 13, 0, 1] <= [int(comp) for comp in re.split('[.-]', foo)[0:4]] <= [4, 13, 0, 21]

Или использовать специально предназначенные средства для сравнения версий типа libversion.

slovazap ★★★★★ ()

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

И вот недавно подловил жену, пыхтящую над её всеобъемлющим регэкспом уже несколько часов. Хорошо, что за зряплату.

Регэкспы, кроме простейших, вредные.

mv ★★★★★ ()
Ответ на: комментарий от anonymous

Неосилятор просто. В нормальных языках есть и библиотеки регекспов и дебаг-флаги.

Ну понятно, что неосилятор. Когда начинаешь учитывать время, потраченное на соченение и отладку регэкспов, то они не очень-то и эффективные. Ну, кроме самых тривиальных.

И раз про эффективность речь зашла, то они (libpcre) и ещё и тормозные. С прекомпиляцией тоже.

mv ★★★★★ ()
Ответ на: комментарий от mv

Ну понятно, что неосилятор

Вместо иронии и отмазок — лучше подтянуть знания.

Когда начинаешь учитывать время, потраченное на соченение и отладку регэкспов, то они не очень-то и эффективные.

ну и какие регекспы ты сочиняешь, когда давно уже есть что-то вроде:

Currently available are:

Regexp::Common::balanced

Provides regexes for strings with balanced parenthesized delimiters.

Regexp::Common::comment

Provides regexes for comments of various languages (43 languages currently).

Regexp::Common::delimited

Provides regexes for delimited strings.

Regexp::Common::lingua

Provides regexes for palindromes.

Regexp::Common::list

Provides regexes for lists.

Regexp::Common::net

Provides regexes for IPv4, IPv6, and MAC addresses.

Regexp::Common::number

Provides regexes for numbers (integers and reals).

Regexp::Common::profanity

Provides regexes for profanity.

Regexp::Common::whitespace

Provides regexes for leading and trailing whitespace.

Regexp::Common::zip

Provides regexes for zip codes.

?

Приведи пример того, что ты парсишь, что приходится «соченять» здесь, и отлаживать теряя своё эффективное время.

И раз про эффективность речь зашла, то они (libpcre) и ещё и тормозные. С прекомпиляцией тоже.

Чем заменишь? Что эффективнее всего для всех случаев?

Deleted ()
> '4.13.0-223-fufufu' ~~ / '4.13.0-' (\d ** 1..3) <?{ 1 <= $0.Int <= 21 }> '-' .* /
Nil
> '4.13.0-22-fufufu' ~~ / '4.13.0-' (\d ** 1..3) <?{ 1 <= $0.Int <= 21 }> '-' .* /
Nil
> '4.13.0-21-fufufu' ~~ / '4.13.0-' (\d ** 1..3) <?{ 1 <= $0.Int <= 21 }> '-' .* /
「4.13.0-21-fufufu」
 0 => 「21」
> '4.13.0-1-fufufu' ~~ / '4.13.0-' (\d ** 1..3) <?{ 1 <= $0.Int <= 21 }> '-' .* /
「4.13.0-1-fufufu」
 0 => 「1」
> '4.13.0-0-fufufu' ~~ / '4.13.0-' (\d ** 1..3) <?{ 1 <= $0.Int <= 21 }> '-' .* /
Nil

Держи по стандарту Perl 6. Сперва литерал с мажорной версией, потом от 1 до 3 цифр в первой группе, потом первую(суть нулевую, на самом деле, `$0`) группу конвертируем в Int и смотрим по диапазону, если True, то регулярка продолжается, иначе не проходит, потом литерал тире и дальше что вздумается.

Выглядит более громоздко, чем pcre, но более читабельно и проще менять, ведь константы можно заменить переменными из конфига, которые потом всё равно отоптимизируют, т.к. блок кода это замыкание.

Lilly ()
Ответ на: комментарий от Deleted

Regexp::Common::zip
Provides regexes for zip codes.

Сразу запретить нафиг. Эти люди не ведают, что творят.

Что эффективнее всего для всех случаев?

Песец. Для всех случаев эффективно не бывает.

anonymous ()
Ответ на: комментарий от anonymous

Сразу запретить нафиг. Эти люди не ведают, что творят.

Аргументный аргумент. Ты если что, не стесняйся в более обоснованных возражениях выражаться. Обещать не могу, но если претензия будет достойной, я подсуечусь или патчем, или фичреквестом, или багрепортом.

Песец. Для всех случаев эффективно не бывает.

Я к тому и веду. Недостаточно сказать, что pcre - тормозные. Гле контекст? В частном порядке мне приходилось лисапедить стейт-машины, которые в конкретно моем случае были быстрее регулярки, но это не значит что я откажусь от регулярок потому что они тормознее реализации на коленке ахо-карасика. Бред. Сравнение теплого с мягким.

anonymous ()