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
Ответ на: удаленный комментарий

Зачем приводить ссылки на говносайты, переводящие stackoverflow?

annulen ★★★★★
()
Последнее исправление: annulen (всего исправлений: 1)

Встрой re2 и херачь через него, там для таких случаев строится эффективное дерево поиска.

DELIRIUM ☆☆☆☆☆
()

Батрачишь на дядей кернельца бэкпортящих

mos ★★☆☆☆
()

Вырезать число из строки и сравнить < 22. У тебя регекспы головгного мозга?

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

`4[.]13[.]0`

Тебе же сказали «упростить», а не «исправить». Понаберут людей, которые ТЗ читать не умеют.

anonymous
()

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

На крайняк

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

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

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

perl -e ‘while(<>){ … }’

perl -ne '...'
anonymous
()
Ответ на: комментарий от Thetan

Берегитесь точек.

Сам удивлен, как столько времени не замечал эту ошибку.

Спасибо!

Deleted
()

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

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

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

anonymous
()

perl

заменить это на диапазон

чтобы регулярное выражение осталось читабельным

4\.13\.0-(1..21)-\.*?

mord0d ★★★★★
()
Последнее исправление: mord0d (всего исправлений: 1)
Ответ на: комментарий от anonymous

Нет, надо. Я настаиваю.

$"='|';
/4\.13\.0-(@{[1..21]})\b/;
anonymous
()
Ответ на: комментарий от anonymous

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

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

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

anonymous
()

Читаемей всего atoi и if. А перед этим сплит по точкам и минусам.

4.13.0-([1-9]|1[0-9]|2[0-1])-.*

Это всё, что я смог родить.

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

так не работает

И не должно. Я написал это пока спал на клавиатуре.

mord0d ★★★★★
()

Каким образом можно заменить это на диапазон с 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
()
Ответ на: комментарий от Deleted

Расширения есть специальные, в лисе у меня Google Search Filter стоит.

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

Тред читается после ответа.

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 ★★★★★
()
Ответ на: комментарий от kirk_johnson

Правильный ответ в регулярках это ну просто лол.

«Я не читаю тред», ага. Скопировали неправильный ответ и начали паясничать как всегда.

vodz ★★★★★
()

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

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

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

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
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.