howto:regex

Регулярные выражения используются для поиска совпадения в строках.
К примеру, нужно автоматически загружать все торренты сериала «Ходячие мертвецы» из рассылки RSS. Для этого можно использовать следующее выражение:

/The Walking Dead.*Сезон:/i

Регулярное выражение в общем виде записывается как /строка/флаги. Мы будем использовать флаги i и u.
i означает нечувствительность к регистру, то есть а и А считаются одинаковыми символами.
u – unicode, без этого русские буквы не будут считаться частью слова.

  • . означает «любой символ», *«любое количество». .*любое к-во любых символов.
  • В регулярных выражениях используются и другие специальные символы: ^ $ + ? { } [ ] \ | ( ) и иногда нужно, чтобы они интерпретировались как «обычные» – для этого используется экранирование символом \ (обратный слэш), например:
    1*2 означает «любое к-во 1, потом 2», в то время как 1\*2 будет соответствовать строке 1*2.
  • Если регулярное выражение записывается как /строка/i, то слэш / тоже является специальным символом.
    Для использования в /строке/i его тоже надо экранировать: /https?:\/\/domain\.tld\/\S/i.
    Здесь s? означает «s либо ничего», а для того, чтобы . в domain.tld интерпретировалась именно как точка, а не как «любой символ», она экранирована: \.
    \Sлюбой символ, не являющийся пробелом

    Это выражение соответствует любому http или https URL для domain.tld c непустым путем, например http://domain.tld/wiki/ или https://domain.tld/images/photo.png.

Если выражение должно содержать слэш, то, чтобы избежать громоздкого экранирования, его можно записать иначе: %выражение%i или #выражение#i,
тогда предыдущее выражение будет выглядеть так: #https?://domain\.tld/\S#i

Вернемся к «Ходячим мертвецам». Выражение /The Walking Dead.*Сезон:/i «найдет» все нужные торренты, однако оно совпадет и с другим сериалом Бойтесь ходячих мертвецов / Fear the Walking Dead / Сезон: 7, что уже не очень хорошо. Можно, конечно, добавить в регулярное выражение и русское название, но мы ведь не ищем легких путей? На самом деле иногда бывает несколько вариантов перевода, так что правильнее ограничиться оригинальным названием.

Оригинальное название заключено между слэшами с пробелами – / The Walking Dead /. Учтем тот факт, что с релизер может ошибиться с пробелами (пропустить или использовать 2+ пробела), так что используем специальный символ * («любое количество»):
/ *The Walking Dead */ *Сезон:. Чтобы не экранировать слэши, используем в качестве ограничителей #, и в итоге получится #/ *The Walking Dead */ *Сезон:#i

Немного усложним задачу –- мы не хотим скачивать большие раздачи всех сезонов этого сериала, так что мы должны исправить выражение так, чтобы оно не совпадало со строкой Ходячие мертвецы / The Walking Dead / Сезон: 1-10 из 10 / Серии: 1-153 из 153.
Проанализируем «правильную» подстроку Сезон: 11 / Серии … – в ней после слова Сезон идет номер сезона и слэш. Учитывая, что \d означает «любая десятичная цифра», а +«один или больше», запишем:

#/ *The Walking Dead */ *Сезон: *\d+ */#i


Еще один пример – выборка всех раздач футбола в хорошем качестве на русском или английском языке. Пример названия такой раздачи:
Чемпионат Нидерландов. Eredivisie 2022-2023 / 4-й тур / Утрехт (Утрехт) - Аякс (Амстердам) / Setanta Sports 1 HD [28.08.2022, Футбол, IPTV/1080i/25fps, TS/H.264, RU-EN]

Нам понадобятся следующие конструкции:

  • \b«граница слова». Словом считается все, состоящее из букв, цифр и подчеркивания
  • [abcd…]любой из символов abcd…
  • (яблоко|груша|персик) – любое из слов яблоко, груша, персик

Соберем всё это вместе.

  • Хорошим качеством мы сочтем разрешение в 1080 (это 1080i и 1080p), так что учтем оба варианта: 1080[ip]
  • Русский и английский пишутся как RU и EN, но встречается и RUS / ENG – это будет (RUS?|ENG?)
    Напоминаем, что S? означает «S либо ничего», то есть RUS? соответствуют и RUS и RU
  • C разделителями и пробелами могут быть разные варианты, так что будем использовать «границу слова»\b
  • Для правильной работы \b с русскими буквами нужен флаг u
  • Слэшей у нас нет, так что используем стандартные ограничители /

/Футбол\b.*\b1080[ip]\b.*\b(RUS?|ENG?)\b/iu

По умолчанию регулярное выражение может соответствовать любой части строки. Если нужно «привязаться» к её началу и/или концу, используйте ^ и $

/^начало…конец$/i «найдется» в Начало закончилось, начался конец, но не в Что-то началось, но конец еще не близок


Конечно же, мы рассмотрели только очень малую часть синтаксиса регулярных выражений. Надеемся, что для задач выборки по названиям раздач этого достаточно. Если же нет – читайте официальную документацию здесь и здесь (надеемся, что до этого дело не дойдет :-)).
Или же загуглите «регулярные выражения для начинающих», но букв там будет еще больше.

Здесь можно (и нужно) протестировать регулярное выражение перед тем, как включать на загрузку соответствующее RSS-правило. Выбирайте Flavor PCRE и не забывайте флаги.

Если будут сложности – обратитесь в нашу поддержку (контакты внизу страницы)

  • howto/regex.txt
  • Последнее изменение: 2022/08/30 11:02
  • (внешнее изменение)