Комментарии 34
Символ латыни - это примерно как цифры математики, лучше или латинский алфавит или латиница, кроме этого, \s - это не только пробел, а все пробельные сущности и их несколько. Время от времени приходиться использовать сложные регулярки (если что, я не программист) для поисков в текстах, html, коде и т.п. поэтому пришлось разобраться с этим, но помню время, когда это все выглядело как китайская грамота)). А еще есть онлайн сервисы, которые помогают сэкономить время типа regex101.com, может кому-то ссылка пригодится
Вопрос по пятому совету по оптимизации: каким образом экранирование может влиять на скорость выполнения?
Есть особая каста разработчиков, который хотят быть во всём уверены и клепают экранирование везде, даже там где в этом нет необходимости. В таком случае тот же движок Regex в .NET будет обрабатывать лишние операции, что приведёт к замедлению обработки строки по паттерну.
Отлично! Я бы ещё в советы добавила "Именуйте группы, пожалуйста". Это очень упрощает дальнейший разбор. Самим же потом вспоминать "а что я тут имел ввиду?". Особенно когда регулярка выглядит как забор.
Регулярки отлично подходят для единоразовых скриптов, но в production-ready коде что-то сложнее пяти символов является потенциальной проблемой. Их сложно читать, в них сложно искать ошибки, они могут интерпретироваться немного по-разному, у них разная поддержка юникода.
Если задача хорошо решается без них, то лучше их не использовать. В ином случае -- обязательно покрывать тестами.
Можно посмотреть, как выглядят регулярные выражения для телефонов разных стран. Можете ли вы легко понять формат индийских номеров?
(\+*)((0[ -]+)*|(91 )*)(\d{12}+|\d{10}+))|\d{5}([- ]*)\d{6}
А регулярка для email даже имеет свой сайт.
Для этих целей можно использовать построитель регулярных выражений с человеческим видом, например https://github.com/bcwood/FluentRegex
Я в python использую флаг re.VERBOSE, что позволяет писать регулярку в несколько строк, добавлять комменты и пр.
# Stupid demo. Same as re.compile(r"\d+\.\d*")
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.VERBOSE)
исправьте, пожалуйста, ошибку:
для выражения [0-9]* "abs" тоже позитивный результат
Для регулярного выражения \+7 значение “++7” будет позитивным, а не негативным результатом.
для выражения [0-9] {3} строка “5123” и для выражения [0-9] {3,5} строка “125123” дадут позитивный результат
Данные примеры больше для понимания разработчиков уровня Junior, понятно что для полного правильного кейса стоит использовать ^\+7$. При таком паттерне мой пример будет корректный, но всё таки это больше статья для начинающих поэтому не стоит усложнять примеры)
про greedy/lazy ни слова? значит, скоро познакомитесь через новые седины
и не забываем классиков:
> Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.
А в чем смысл делать английский заголовок для русской статьи?
t=20181125T142800&s=850.12&fn=8715000100011785&i=86841&fp=1440325305&n=1
Это как раз неудачный пример для парсинга регулярками. А что вы будете делать, если порядок параметров изменится? Тут логичней было бы дробить строку сплитом сначала по &
, потом по =
, далее определять имя параметра и парсить его значение стандартными методами. Т.е. тут вообще можно без регулярок обойтись.
Хорошие практики и советы по оптимизации
Еще забыли: если можете обойтись без регулярок — не используйте их. А также имейте представление о контекстно-свободных парсерах.
Еще забыли: если можете обойтись без регулярок — не используйте их.
Нельзя с этим не согласиться. Тем не менее, если предположить, что нужна регулярка, выбор автора, имхо, требует какого-то дополнительного обоснования (если скорость, то зачем в этом случае регулярка...), т.к. можно распарсить такую строку гораздо проще и в более общей форме (вне зависимости от ключей и их порядка):
Нельзя с этим согласиться.
Если какую-то проблему можно решить регуляркой, то почему бы это не сделать?
Принимать решение исключительно "так я могу это сделать и без регулярки, значит не буду пользоваться" - это не аргумент.
Регулярка - просто инструмент. И если он где-то упрощает жизнь - то пользуйтесь.
Если какую-то проблему можно решить регуляркой, то почему бы это не сделать?
Вы всегда легко можете посчитать сложность Вашей регулярки? Я не один раз сталкивался с случаями, когда решение на регулярке неприемлемо быстро убивало скорость при увеличении входной строки. Кроме того, убористая регулярка, конечно, тешит самолюбие, но уже чуть позже с большим трудом читается самим её автором. Может, где-то есть общество людей (отдельные гении не считаются), которые всегда легко читают регулярки и понимают их сложность, но я не удостоился с таким столкнуться.
И если он где-то упрощает жизнь - то пользуйтесь.
Да пользуюсь, пользуюсь. :) До сих пор горжусь арканными заклинаниями (то, что получилось, иначе не назовёшь), которые написал на прошлой работе для чтения и редактирования легаси-конфиг-файлов на перле (когда конфиг это код на языке перл, и уже никто не расскажет, почему). Надеюсь, что те, кто сейчас поддерживает этот код, не знают, где я живу.
Например, в PHP это функция parse_str.
Паттерн ^(?:8|+7)[0-9]{10}$
В ваш паттерн российских номеров совершенно случайно попал весь Казахстан.
[0-6,8,9]{10} будет чуть точнее.
В российских номерах не бывает семёрок?
Принципы и идеи, заложенные в его работах, были практически реализованы Кеном Томпсоном и с его лёгкой руки проникли в язык Perl.
Насколько я знаю, Кен был тем, кто реализовал их в ed, grep и др.
А в Perl они были впервые реализованы уже в самом языке, а не при помощи внешней библиотеки. И Гвидо реализовал гораздо больше, чем было в изначальных extended regexp.
И уже после Perl появилась свободная библиотека PCRE, на базе которой регулярки появились в других языках.
– означает что предыдущее условие до данного символа, может встречаться один или несколько раз или вовсе не будет (соответственно может повторятся)
Какой-то странный перевод. Что такое "условие" неоднозначно. Было бы лучше пояснить правильную терминологию - что такое мета-символ, что такое якорь, что такое квантификатор. А тут, как в очень многих других "не очень" инструкциях, просто вываливают какое-то количество знаков, которое нужно заучить наизусть.
Уж проще почитать справку на regex101
Помню в середине 90-х, когда B-деревья были большими, мне потребовалось реализовать что-то типа сопоставления с образцом на Borland C++ 3.1 под DOS на 80286-м. Интернета еще не было не у всех не, я не знал, что «все уже украдено до нас», и поэтому по сути пришлось изобретать регулярные выражения (с упрощенным и извращенным синтаксисом, естественно). Через несколько лет интернет завезли, и я узнал о PCRE. И мне даже удалось ее скомпилировать в BC3.1! Правда, там было несколько десятков тысяч строк кода, и размер получавшегося exe-шника не лез ни в какие ворота (да и компилировалось оно добрых минут 20 на 80286, постоянно упираясь в память), так что дальше забавного эксперимента это никуда не пошло.
Немного иронично что в статье "Regex for lazy developers" нет никакой информации про lazy выражения: https://regex101.com/r/id4r4i/1
Достатошно полезная штука, особенно в HTML.
\w ≡ [a-zA-Z0-9_] – любой символ латыни, все числа и _
В общем случае это неверно.
\w - это Символ «слова». В зависимости от реализации это может быть не только латиница. В python3 например, в эту маску попадут и символы национальных алфавитов.
Допишите, пожалуйста, пример про экранирование спец. символа
>> \ – экранирование любого спец. символа
По-моему в примере ^\+7\d{10}
вариант +712345678900
это не позитивный результат, поскольку после +7 идет 11 цифр. Вероятно это просто опечатка но немного вводит в заблуждение касательно терминов позитивный и негативный результат.
Regex for lazy developers