2 место Регулярные выражения, что это такое и с чем их едят?

Discussion in 'Четвертый конкурс статей' started by ZennoScript, Dec 2, 2015.

  1. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    Вступление

    В этой статье я хочу рассказать о регулярных выражениях. Для непосвященного пользователя они сложны для понимания, поэтому постараюсь максимально просто, с примерами, показать для чего и как они используются в Zennoposter. Надеюсь, данная статья будет полезна для всех!

    Регулярные выражения достаточно широко используются в программе, а именно:

    - Для поиска элементов;

    - Во время парсинга данных с веб-сайтов или из файла;

    - Для удобства обработки данных из различных источников (замене или удалению фрагментов текста);

    - При установке разделителей в списках и таблицах;

    - Многое другое.


    Регулярное выражение - это язык поиска подстрок в тексте, основанный на использовании специальных символов и указателей. По сути это строка-образец, которая состоит из символов (статического текста) и спецсимволов (символов, обозначающих какие-то последовательности) и задаёт правило поиска подстроки в обрабатываемом тексте.


    Для постройки регулярных выражений в программе есть специальный инструмент – «Конструктор регулярных выражений». В нём можно протестировать готовые выражения, а так же составить свои.

    [​IMG]

    Возьмём текст и составим на его примере регулярное выражение так, чтобы получить домены сайтов:


    <a href="http://site.com">
    <a href="http://sitesite.com">

    В Конструкторе есть раздельные поля - текст, который идет перед искомым (<a href="), с которого начинается (http://), заканчивается искомый текст (.com), что идёт после него (">). В результате мы получим следующее регулярное выражение:
    (?<=<a\ href=")http:.*?\.com(?=">) и список доменов в результатах тестирования.

    [​IMG]

    Так же в Конструкторе имеется два чекбокса:

    1) Разрешить переносы - включает и выключает поиск по тексту с учетом переносов строк (при включении данной опции, регулярное выражение не ограничено поиском в пределах одной строки, а так же учитывает переносы строк);

    2) Самое короткое совпадение - включает и выключает поиск самого короткого совпадения. При включении данной опции, в результатах мы получим самую короткую подстроку, соответствующую составленному выражению. При выключении, соответственно - самую длинную.

    При заполнении этих полей, Ваш текст автоматически преобразуется и в поле "Текст регулярного выражения" будет предоставлено готовое выражение, которое можно использовать для поиска.

    Конструктор регулярных выражений, который есть в программе Zennoposter, достаточно не плох, но не универсален. Он подходит для составления простых выражений, когда мы имеем точные совпадения в тексте - что идет перед или после текста, который нам нужно найти, чем он начинается или чем заканчивается.Иногда, полученный результат бывает не удовлетворительным - строк больше или меньше, чем нужно, или просто вместо искомого текста мы получаем разный мусор. В таких случаях необходимы более широкие знания и правка выражений, сформированных Конструктором, вручную.


    Для того, чтобы правильно самостоятельно составить регулярные выражения, рассмотрим основные символы, определим в какой ситуации они могут использоваться.
     
  2. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    Символьные обозначения:


    «.» - любой символ, кроме переноса строки(\n);

    «\d» - цифровой символ, т.е. любая цифра от 0 до 9;

    «[0-9]» - цифровой диапазон - отличается от \d тем, что в данном виде есть возможность указать не любой цифровой символ, а используя диапазоны, например [1-3], который найдет только цифры 1, 2 и 3;

    «\D» - не цифровой символ. Т.е. все символы - буквенные и пробелы, кроме цифр;

    «\s» -все пробельные символы, которые могут включать в себя:

    - пробел «\ »;

    - новая страница «\f»;

    - возврат каретки «\r»;

    - новая строка «\n»;

    - знак табуляции «\t»;

    - знак вертикальной табуляции «\v»;

    «\S» - не пробельный символ, т.е. все буквы, цифры и знаки. Всё, что не перечислено выше, как пробельные символы.

    «\w» - буквенный или цифровой символ или знак подчёркивания.

    «\W» - любой символ, кроме буквенного или цифрового символа или знака подчёркивания.



    Обозначения границ:


    ^ - начало строки;

    $ - конец строки;

    \b - граница слова;

    \B - не граница слова.



    К примеру, нам нужно проверить, содержит ли строка слово “Красный”, прописав в конструкторе «красный», мы можем получить так же и другие слова, в которые входит данное слово, такие как “прекрасный” и т.д. Что бы этого не происходило, необходимо прописать \bкрасный\b - таким образом, все слова, которые могут быть похожи на искомое учитываться не будут.

    Не граница слова, соответственно, работает наоборот. К примеру, мы знаем, что слово должно заканчиваться на “жили”, но само слово “жили” нам не нужно, тогда мы прописываем \Bжили и получаем список слов с нужным нам окончанием - дорожили, выжили и т.д.



    Обозначения количества совпадений (Квантификаторы):


    {5} - ровно 5;

    {1,5} - от 1 до 5 включительно;

    {1,} - от 1 и более;


    ? - ноль или одно, так же соответствует {0,1};

    * - ноль или более, так же соответствует {0,};

    + - Одно или более, так же соответствует {1,}.


    Квантификаторы устанавливаются после символов, число повторений которых необходимо задать.

    Возьмём для примера точку, которая обозначает любой символ, и составим регулярное выражение, которому будет соответствовать любая последовательность из 4 символов. Результат будет выглядеть таким образом: .{4}

    Так можно указать, что внутри искомого текста имеется установленное или неограниченное число повторений установленных символов, т.е.:

    с.{2}л - такое регулярное выражение найдёт такие слова, как стол, стул и т.д., но ему так же будет соответствовать строка, имеющая в середине пробелы, цифры и прочее.

    [​IMG]

    Для того, чтобы указать, что внутри будут только буквы, необходимо прописать таким образом:

    c[а-я]{2}л

    [​IMG]

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

    Для указания диапазонов используется тире между значениями. Для перечисления, символы просто прописываются в строку без каких либо разделителей.

    [a-zA-Z1-5абв] - данная последовательность обозначает любую английскую букву в верхнем и нижнем регистре, числа от 1 до 5 включительно, а так же русские буквы а, б и в.


    Регулярное выражение будет иметь такой вид:

    с[тоу]{2}л

    Мы обозначаем, что после буквы “с” идут 2 любых символа, указанных в квадратных скобках и данная последовательность найдёт слова стол и стул, но ему так же будут соответствовать последовательности букв “суул”, “сутл” и прочие.

    Модификаторы:

    (?i) - включает нечувствительность выражения к регистру символов;
    (?-i) - выключает нечувствительность выражения к регистру символов.


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

    Пример использования:
    [​IMG]
    [​IMG]

    Так же бывают случаи, когда в одном месте регистр для нас не важен, а в другом важен.

    Пример использования:
    [​IMG]


    Данное регулярное выражение найдёт строку “Test, TEST”, т.к. у первой фразы включена нечувствительность к регистру и она находит все совпадения, но не найдёт “TEST, Test”, т.к. во второй фразе должно быть точное совпадение по регистру.


    Модификаторы многострочного поиска:

    (?m) - включает многострочный поиск

    (?-m) - отключает многострочный поиск



    Для того чтобы найти все строки, начинающиеся с не пробельного символа, подойдёт такое регулярное выражение:

    (?m)^\S.*

    Символы, которые должны экранироваться, для того, чтобы они учитывались в регулярном выражении как текст, а не как часть регулярного выражения (метасимволы):

    ^ [ . $ { *

    ( \ + ) | ?​


    При использовании данных символов в регулярном выражении, как части текста, они должны экранироваться знаком \.

    К примеру, если в тексте у вас должен находиться знак вопроса, он обозначается как \?
     
    Last edited: Dec 2, 2015
    orka13, udder, impul5e and 19 others like this.
  3. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    Рассмотрим детально основные случаи использования символов регулярного выражения.

    .{5,10} - данному регулярному выражению соответствует последовательность от 5 до 10 любых символов, кроме переноса строки. Его можно использовать для обрезки текста до нужной длины, парсинга подстрок определенной длины, а так же для указания нужного количества неизвестного набора символов внутри текста.

    а\d+а - в случаях, когда между искомым текстом, который известен, есть числа, состоящие из разного количества знаков. Данному регулярному выражению соответствует а1а, а23а, а459а и так далее.

    а[2-5]{2,4}а - данное регулярное выражение возьмет текст, который будет начинаться на “а” и содержать внутри от 2 до 4 цифр 2, 3, 4 или 5 и будет заканчиваться на “а”. К примеру, а354а или а52а

    К примеру, вам необходимо взять url сайта из следующей строки id="123" <a href="www.site.com">, где номер id всегда меняется, а просто в теге a href находятся и другие урлы, которые не нужны.

    Тестер регулярных выражений выдаст нам такой вариант:

    (?<=id="123"\ <a\ href=").*?(?=">)

    но ему будут соответствовать только строки, айди которых равен «123». Т.к. нам нужно указать, что вместо 123 может быть любая последовательность цифр, мы заменяем их на \d+ и получаем следующее регулярное выражение

    (?<=id="\d+"\ <a\ href=").*?(?=">)

    которое получит все строки, содержащие любые айди.

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

    Если мы возьмём строку <a href="www.site.com"> <a href="www.site2.ru"> и применим к ней регулярное выражение “(?<=<a\ href=").*?\.ru(?=">)”, в ответе мы получим www.site.com"> <a href="www.site2.ru вместо ожидаемого «www.site2.ru»

    Почему поиск выдал нам не самое короткое совпадение? Происходит это потому, что регулярное выражение получило из текста первую часть, которая должна идти перед искомым текстом, т.е. “<a href="”. Далее продолжило искать до тех пор, пока не нашло условие, по которому должна закончиться строка, т.е. “.ru”, после которого идёт ">

    Для того, чтобы этого избежать, в данном случае можно использовать такую структуру регулярного выражения:

    (?<=<a\ href=")\S+?\.ru(?=">)

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


    В случае же, если в части регулярного выражения может быть всё, что угодно - различной длины различный текст, или же он может вообще отсутствовать, можно в данном месте вставить последовательность «.*?»

    Начало и конец строки

    Для указания того, что искомое значение начинается с новой строки и (или) заканчивается в конце строки, подойдёт такое регулярное выражение:

    ^строка$

    Часто такое обозначение помогает построить правильное регулярное выражение для поиска элементов на вебстранице.


    В случаях, если мы ищем элемент на разных сайтах, и он может отображаться с разным регистром, к примеру: Строка, СТРОКА, строка. С точки зрения машины эти три значения будут различными, и найдется только то, которое прописано с учетом регистра.

    Если нужно подготовить регулярное выражение, которое найдет все эти совпадения, необходимо прописать

    (?i)^строка$

    т.е. мы отключаем у регулярного выражения чувствительность к регистру и дальше уже прописываем само регулярное выражение. В таком виде найдутся все совпадения, независимо от регистра.

    Если необходимо взять текст с вебстраницы, почты или файла, то нужно учитывать, что начало строки, обозначаемое, как ^ - это только начало первой строки текста, а конец строки, обозначаемое как $ - это только конец последней строки.

    Остальные строки в тексте имеют переносы, т.е. все эти строки заканчиваются символом возврата каретки (\r) а начинаются символом новой строки (\n).

    Для того, чтобы обозначить, что регулярное выражение должно начинаться и заканчиваться в пределах одной строки, мы можем прописать условие ИЛИ, которое обозначается как вертикальный слеш - |

    Регулярное выражение выглядит так:

    (?i)(\n|^)строка(\r|$)

    Так же можно дополнительно использовать модификатор многострочного поиска, который каждую строку считает, как новую:

    (?im)^строка

    Подробнее об операторе ИЛИ


    В регулярном выражении можно указать, что именно искать, используя оператор ИЛИ следующим образом:

    1|2 (что будет обозначать выбор 1 или 2).

    Таким образом, мы можем проверять на странице наличие сразу нескольких текстов.

    К примеру, Вам необходимо проверить на странице фразы "Привет", "Спасибо за регистрацию", "Приветствуем Вас", мы можем объединить все эти данные в одно регулярное выражение следующим образом:

    Привет|Cпасибо за регистрацию|Приветствуем Вас

    При таком построении, проверка наличия текста на странице получит один из указанных вариантов.

    В случае же, если знак “ИЛИ” необходимо использовать не для всего регулярного выражения, как показано выше, а только для его части, эта часть должна находиться внутри скобок. Например:

    Что (Он|Она|Они) дела(е|ю)т\.

    Данное регулярное выражение найдет фразы "Что Он делает." "Что Она делает." и "Что Они делают."


    Еще несколько примеров готовых регулярных выражений:


    <.*?> - найдет все теги в искомом тексте;

    [\.\-_A-Za-z0-9][email protected][\.\-A-Za-z0-9]+?[\.A-Za-z0-9]{2,} - найдет все email;

    (\d{1,3}\.){3}\d{1,3}:\d{1,5} - получить айпи и порт;

    (http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])? – получит урлы сайтов.


    Всем спасибо, кто осилил данную статью, надеюсь она была полезна прочитавшим её пользователям и пригодится еще многим.
     
    Last edited: Dec 2, 2015
    orka13, enjoy1337, Ikigai and 37 others like this.
  4. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,967
    Likes Received:
    1,789
    а теперь апать каждых 3 часа хотя бы что бы на виду всегда было, а то реально по пустякам пишут ленясь в поиске поискать
     
    orka13, SHoro and svaminar like this.
  5. svaminar

    svaminar Client

    Joined:
    Aug 21, 2013
    Messages:
    841
    Likes Received:
    359
    и шаблон для апа. Все таки форум про зенку
     
    Irridian, SHoro, SilverSun and 2 others like this.
  6. Gfoblin

    Gfoblin Client

    Joined:
    May 30, 2013
    Messages:
    4,014
    Likes Received:
    808
    Да надо попросить ее закрепить однозначно!
     
  7. AlisaZ

    AlisaZ Client

    Joined:
    Sep 17, 2014
    Messages:
    74
    Likes Received:
    98
    Да что там закрепить - прямиком статейку в ВИКИ по Зеннке!!! :cp:
     
    SHoro and искра like this.
  8. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,967
    Likes Received:
    1,789
    если бы народ ещё по вики переходил, мне кажется надо при входе на форум сделать так что бы это окно сразу открывалось
     
  9. Lite

    Lite Client

    Joined:
    Oct 17, 2013
    Messages:
    197
    Likes Received:
    47
    Что сделано неправильно? По логике должно выдаваться только имя файла, но выдается весь путь.
    [​IMG]
     
  10. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,967
    Likes Received:
    1,789
    \w+.*?(?=\.txt) так попробуй
     
  11. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    http://joxi.ru/J2bVoW3S4xkjZ2 ну вот же в статье именно по этому случаю описывается, почему так.
    В Вашем случае поможет регулярка
    Code (text):
    1. (?<=/)[\w\d-\.]*?(?=\.txt)
    - т.е. не всё, что попало, а указать символы, которые могут идти в этом месте, исключая всё ненужное.
     
  12. awm

    awm Client

    Joined:
    Nov 2, 2011
    Messages:
    132
    Likes Received:
    20
    Регулярки сколько собираюсь изучить, все не доходит до них, а временами при парсинге встроенным тестером не получается составить- вечно лезет что то лишнее.
     
  13. Batya

    Batya Client

    Joined:
    Apr 6, 2015
    Messages:
    98
    Likes Received:
    14
    Здравствуйте! А с моей проблемой не поможете разобраться? Там всё намного сложнее, потому метод решения предложенный выше не сработает, но проблема в том же. Хватает не самые короткие совпадения. http://zennolab.com/discussion/threads/reguljarnye-vyrazhenija.23866/#post-163834
     
  14. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    Добрый день!
    Напишите в личку, опишите более детально задачу. От куда и что берёте. Надо сайт посмотреть.
     
  15. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    Помогите такая ситуация как вставить в конструктор регулярки в поле перед искомым текстом
    <h5>
    <a href=
     

    Attached Files:

    • 1.JPG
      1.JPG
      File size:
      51.6 KB
      Views:
      491
    • 2.JPG
      2.JPG
      File size:
      82.1 KB
      Views:
      488
    LightWood likes this.
  16. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    Добрый день! Вы можете вставить в конструктор просто <h5><a href= и потом между ними дописать, что там идёт какое-то число пробельных символов, т.е. \s+
    В итоге получите
    Code (text):
    1. (?<=<h5>\s+<a\ href=).*
     
    yreha likes this.
  17. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    Спасибо!
     
  18. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    Скажите а как получить ячейку с n-листа ексель.
     
  19. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
    А при чем тут регулярные выражения?
    Это можно сделать при помощи дополнительных библиотек и C# кода.
     
    yreha likes this.
  20. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    не подскажите где есть примеры? очень надо. спасибо
     
  21. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
  22. ssXXXss

    ssXXXss Client

    Joined:
    Dec 23, 2014
    Messages:
    6,967
    Likes Received:
    1,789
    надо вместо кнопки "нравится" благодарение сделать по 20 руб, так смотри за год в 10 раз набежит больше чем за изготовление проектов ))
     
    ZennoScript likes this.
  23. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    как убрать символ квадратик в строке пробовал через замену {-String.Enter-} не помогает
     
  24. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
  25. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    не помогло
     
  26. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
  27. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    тоже не работает может я не то делаю
     

    Attached Files:

    • 22.jpg
      22.jpg
      File size:
      36.2 KB
      Views:
      419
  28. ZennoScript

    ZennoScript Moderator

    Joined:
    Mar 4, 2011
    Messages:
    4,410
    Likes Received:
    1,717
  29. yreha

    yreha Client

    Joined:
    Nov 19, 2015
    Messages:
    125
    Likes Received:
    3
    \r|\n сработало ура спасибо!
     
  30. trapni

    trapni Client

    Joined:
    Oct 16, 2013
    Messages:
    289
    Likes Received:
    22
    http://site.ru/2015/11/03/
    http://site.ru/2015/11/04/
    http://site.ru/2015/11/11/stat-stat/
    http://site.ru/2015/12/11/stat1-stat1/


    Подскажите пожалуйста, реально ли как-то удалить строку(и) только с числами, т.е первую и вторую? Получить только "stat-stat/", "stat1-stat1/" или две последние строки целиком? Или проще говоря, как избавиться от двух верхних строк )) ?
     

Пользователи просматривающие тему (Пользователей: 0, Гостей: 0)