Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Регулярные выражения

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

Открыть новую тему     Написать ответ в эту тему

leftMIND

Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
   Регулярные выражения
Обучающий материал
  • Книги    
  • Шпаргалки: от AZJIO (AutoIt3, PCRE) от Dave Child
  • wikipedia.org - Регулярные выражения на wiki  
  • edlinsoft.blogspot.com - Регулярные выражения в .NET Framework  
  • php.ru - Синтаксис регулярных выражений  
  • php.net - Синтаксис регулярных выражений  
  • regexpstudio.com - Регулярные выражения для Delphi  
    Официальные источники:
  • docs.notepad-plus-plus.org - Официальный источник Notepad++ (англ. яз.)  
  • pcre.org - Официальный справочник движка PCRE (англ. яз.)  

  •    Тестирование регулярных выражений
    Программы
    Онлайн сервисы
  • RegexBuddy - крутая и платная  
  • RegExp - бесплатно, AZJIO, PCRE, AutoIt3  
  • Expresso  
  • The Regex Coach  
  • RegExstar, Github (AutoHotKey, PCRE)
  • Обзор программ от ManHunter    
  • regexr.com здесь в Community множество готовых регулярных выражений  
  • pagecolumn.com - для javascript  
  • pagecolumn.com - для php  
  • cuneytyilmaz.com - для javascript  
  • php-include.ru - на флеш-плеере  
  • regex101.com  
  • easyregexp.ru  
  • debuggex.com - показывает структурно  

  •    Схожие темы
  • javascript регулярные выражения
  • PHP: Регулярные выражения (RegExp, Regular, eregi, preg)
  • Игра - Регулярно выражайтесь!
     
    первое сообщение темы...
    Обсуждение шапки данной темы ведётся в этой теме
    Рекомендации по составлению вопросов в данной теме:

  • Всего записей: 33 | Зарегистр. 07-04-2002 | Отправлено: 23:55 15-10-2002 | Исправлено: AZJIO, 15:18 12-02-2021
    Nikolai2004



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81

    Цитата:
    Variable-length look-behind

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

    Всего записей: 1523 | Зарегистр. 07-01-2004 | Отправлено: 22:03 23-01-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Nikolai2004

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

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

    Код:
    (?<=\b\w{1,2})\d

    Текст:

    Цитата:
    a1
    ab1
    abc1

    Эта регулярка находит текст a1, ab1 но не abc1 в программах JGSoft, новом JavaScript из V8 и .NET.
    Большинство перло-подобных диалектов так сделать не дадут. Для них в этом регулярном выражении ошибка -  variable repetition inside lookbehind - т.е. заглядывание назад переменной длины. А это очень нужный функционал для интенсивной обработки текста в редакторе, в частности в контексте создания словарей.
    Понятное дело, что пример простейший. Но отражает сам принцип. В EditPad, к примеру, вы можете указать сколь угодно сложное выражение в этом самом блоке lookbehind, в том числе вложенные конструкции в со своими lookbehind или lookahead, в т.ч. переменной длины.

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 00:44 24-01-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Ещё практический пример. Проверка множественного экранирования обратным слешем.

    Код:
    (?<=(?<!\\)|(?<!\\)(?:[\\]{2})+)

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

    Код:
    (?<=(?<!\\)|(?<!\\)(?:[\\]{2})+)(?:\[(?:(?:\/?(?:[\*'bcimpstu]|com|ex|ref|trn|!trs|su[bp]|url))|(?:m\d|c\x20[a-z]{3,20}|lang(?:\x20(?:id=\d{1,5}|name="[A-Za-z]{5,22}"))|ref(?:\x20dict="[^\r\n"]+")|br)|\/lang)\]|[\\#@~^]|{{.*?}}|<<|>>)

    Такая регулярка не работает в перло-подобных диалектах. Более того, мне не известен способ достичь подобного функционала в рамках синтаксиса Perl/PCRE/etc. На данный момент работает только в JGSoft, .NET и JavaScript V8 (Chrome, Node.js).

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 18:48 24-01-2019
    Nikolai2004



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    мне тяжело понять даже концепцию lookbehind, куда уж там до variable-length внутри неё
    но ладно, может когда-нибудь доросту. пока EmEditor с его boost library меня всем устраивает.
    тем более, что в EditPad нет очень полезной функции работы с CSV-таблицами

    Всего записей: 1523 | Зарегистр. 07-01-2004 | Отправлено: 18:58 26-01-2019
    AZJIO



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81
    (?<=...) просмотр назад можно конечно организовать без использования этим способом, а просто сделать обычную регулярку с группой, но пошаговый поиск с возвращением начало поиска назад на ширину этой группы и с контролированием позиции найденного, если та же позиция то не добавлять искомое. Ну это конечно программно. А при обычном поиске просто не используешь группу добавляя (?:...) или \K, но опять же что мы делаем подсчёт, проверку вхождения, валидность? Просто те кто не добавили возможность просмотра назад переменной длины возможно предвидели проблему как это будет действовать в разных условиях, когда искомое и просмотренное назад одинаковое, когда просмотренное назад можно по всякому интерпретировать, это не тоже самое что искать общую регулярку, а именно найти искомую и проверить что перед ней стоят символы. Иначе пришлось бы много раз проверять предыдущую часть текста на вхождение регулярки конец которой совпадал бы с началом найденного. То есть это сделать можно но не в универсально быстрой концепции просмотра назад.

    Всего записей: 4404 | Зарегистр. 03-05-2006 | Отправлено: 06:24 30-01-2019 | Исправлено: AZJIO, 06:40 30-01-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    AZJIO (post)

    Цитата:
    Ну это конечно программно.

    В том то и дело. Раньше в JS так и делал - по глобальному exec и потом отдельной проверкой первой группы на чётность. С поддержкой variable-length такая необходимость отпадает. Хотя, вопрос что быстрее остаётся открытым.

    Цитата:
    А при обычном поиске просто не используешь группу добавляя (?:...) или \K

    Группу (?:...) использую всегда по возможности. Но \K не использую - эта фича поддерживается далеко не везде. Конкретно в тех диалектах, с которыми я работаю, её нет.

    Цитата:
    То есть это сделать можно но не в универсально быстрой концепции просмотра назад.

    Да, здесь основная проблема - быстродействие. Я тоже предполагаю, что внедрить поддержку variable-length технически не проблема. Проблема возникает с плохо-составленными регулярками. Особенно если в (?<=...) присутствует точка в многострочном режиме. Там будет просто сумасшедшее кол-во бактраков. Всё повиснет намертво на большом тексте. Эту фичу надо пользовать с умом. Например, я перед тем как смотреть назад, сначала смотрю вперёд:

    Код:
    (?=[abc])(?<=...)[abc]

    На практике, та регулярка "strip DSL tags" будет выглядеть так:

    Код:
    (?=[<>@[\\^{~])(?<=(?<!\\)|(?<!\\)(?:\\{2})+)(?:\[(?:(?:\/?(?:[\*'bcimpstu]|com|ex|lang|ref|trn1?|!trs|su[bp]|url))|(?:m\d|c\x20[a-z]{3,20}|lang\x20(?:id=\d{1,5}|name="[A-Za-z]{5,22}")|ref(?:\x20dict="[^\r\n"]+")|br))\]|[\\@~^]|{{2}[\s\S]*?}{2}|<{2}|>{2})

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 11:28 30-01-2019
    gerxer

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Как сделать чтобы несколько условий выполнялось в выражении, например выделить все строки начинающиеся на C ^c, и которые не содержат запятых ^[^\n,]+$?

    Всего записей: 565 | Зарегистр. 19-06-2014 | Отправлено: 20:19 02-02-2019
    YuS_2



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    gerxer

    Цитата:
     и  

    Это условие предполагает такой шаблон:

    Код:
    ^c[^\n,]+$

     
    А вот на счет:

    Цитата:
    выделить все строки

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

    Всего записей: 3218 | Зарегистр. 03-02-2009 | Отправлено: 21:12 02-02-2019
    gerxer

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    YuS_2
    Странно почему у меня сразу не получалось когда пробовал так ^c[^\n,]+$.  
    А если не знак, а слово нужно отфильтровать в c[^\n...]+$, то тогда как?

    Всего записей: 565 | Зарегистр. 19-06-2014 | Отправлено: 23:43 02-02-2019
    Jonmey

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    gerxer

    Цитата:
    А если не знак, а слово нужно отфильтровать в c[^\n...]+$, то тогда как?  

    Примеры
    (?(?!(^с[^\n\r]*слово[^\n\r]*$))(^.*$))
    (?(?!(^с.*слово.*$))(^.*$))
    (?(?=(^с.*слово.*$))|(^.*$))

    Всего записей: 1305 | Зарегистр. 17-01-2011 | Отправлено: 05:04 03-02-2019
    gerxer

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Jonmey
    Что-то не срабатывает.

    Всего записей: 565 | Зарегистр. 19-06-2014 | Отправлено: 14:08 03-02-2019
    Jonmey

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    gerxer
    Зависит от используемой программы.
    Программа должна поддерживать lookbehind/lookaround. И кроме этого, зависит как программа разбирает перевод каретки.
    Те примеры для powergrep, которая различает переводы каретки трех типов PC. NIX, MAC потому что отдельно разбирает символы 0D и 0A. В приведенном вами примере движек этого, похоже, не различает, поэтому указан только \n. Если ваша программа отличается в понимании синтаксиса только этим, то уберите из выражений выше сочетания \r
    Но сначала читайте справку к вашей программе насчет поддержки lookbehind/lookaround и его синтаксиса в ней.

    Всего записей: 1305 | Зарегистр. 17-01-2011 | Отправлено: 16:14 03-02-2019 | Исправлено: Jonmey, 16:29 03-02-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Jonmey (post)
    Цитата:
    Примеры

    Вы сами хоть эти регулярки тестировали? Они просто нерабочие. По крайней мере в том виде, в котором они отображены здесь.
     
    gerxer
    Надо найти строки, начинающиеся с w, но не содержащие слово word
    Регулярка, которая должна работать везде:

    Код:
    ^w(?:(?!word)[^\r\n])*$

    Если движок поддерживает сверхжадные (поцессивные) квантификаторы, то более оптимальный вариант:

    Код:
    ^w(?:(?!word)[^\r\n])*+$

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 01:24 04-02-2019 | Исправлено: Romul81, 01:33 04-02-2019
    Jonmey

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81

    Цитата:
    Вы сами хоть эти регулярки тестировали?

    Напр.

    Причем в рамках powergrep работают оба варианта - прямое и обратное направление выбора (IS и NOT IS) в зависимости от выбранного режима работы.

    Всего записей: 1305 | Зарегистр. 17-01-2011 | Отправлено: 02:13 04-02-2019 | Исправлено: Jonmey, 02:26 04-02-2019
    gerxer

    Full Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81
    Не работает, я пытаюсь применить их для поиска по заголовкам словаря в ГД.

    Всего записей: 565 | Зарегистр. 19-06-2014 | Отправлено: 10:47 04-02-2019
    YuS_2



    Silver Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81

    Цитата:

    Код:
    ^w(??!word)[^\r\n])*$

    Правильнее было бы так:

    Код:
    ^w(?!word)(?:[^\r\n](?!word))*$

    т.к. это, всё же, просмотр вперед...
    хотя, если реализация корректна, то Ваш вариант работать будет.
     
    gerxer

    Цитата:
    Не работает

    Значит Ваш редактор не поддерживает lookaround, как минимум...

    Цитата:
    в ГД

    В Государственной Думе?!

    Всего записей: 3218 | Зарегистр. 03-02-2009 | Отправлено: 11:20 04-02-2019 | Исправлено: YuS_2, 11:21 04-02-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Jonmey
    Вы пользуетесь таким замечательным инструментом, как RegexBuddy, но, к сожалению, пока не освоили его в должной мере.
    Всё нижеследующее я скажу не для того, чтобы поумничать, но только лишь с целью внести ясность и обратить ваше внимание на некоторые, неочевидные нюансы, связанные с рег. выражениями, учитывая, что вы, по всей видимости, являетесь человеком, активно ими интересующимся.
     
    Ваша регулярка не делает главного - не отвечает заданному условию и находит не те совпадающие строки, что нужно. Объясню. Первоначальное условие было

    Код:
    ^c[^\n,]+$

    Далее, было пожелание, чтоб вместо фильтра [^\n,] использовать "слово".
    Т.е. логика следующая (fakecode)

    Код:
    line = начало строки + с И НЕ строка содержит "слово" И вся строка

    В вашем случае логика следующая:

    Код:
    line = ЕСЛИ впереди НЕ (начало строки + с + любые символы + "слово" + любые символы + конец строки) ТО вся строка

    Чувствуете разницу? На вашем же скриншоте есть строки, которые НЕ начинаются с C, поэтому не отвечают изначальному условию.
     
    Далее. Вы в своём регулярном выражении используете УСЛОВИЕ (Condition).
    Во-первых эта фича поддерживается далеко не везде. В том же AkelPad её нет, если не ошибаюсь. В JS точно нет. В JGSoft - да, есть.
    Во-вторых, даже при наличии такой поддержки, использование условия является крайне редкой и специфической необходимостью, в реальной жизни редко встречающейся. Большинство регулулярок с условиями можно переписать на стандартный синтаксис без потери в функционале. Говорю из своего опыта. Мне очень хорошо знаком диалект JGSoft, т.к. я в своё время написал подсветку для EditPad для формата DSL. Там полностью всё на регулярках. И от использования условий я полностью отказался в какой-то момент за ненадобностью - вся логика реализуется и без них. От этого быстродействие (критический параметр для подсветки) только выигрывает.
    Но предположим, что ваша логика верна и мы хотим составить рег.выражение её отрабатывающее. В данном случае, опять же, можно обойтись без условия и с выигрышем для производительности. Например так:

    Код:
    ^(?!c.*?\[m1\]).*$

    В чём выигрыш?
     
    1) не используется условие
    2) не захватываются группы
    3) ДО "фильтра" \[m1\] - нежадный квантификатор для предотвращения множественного отката. После - жадный, чтоб захватить всё за один шаг.
    4) на любой другой позиции, отличной от начала строки, регулярка фейлится с одним единственным бэктрэком (идеальная ситуация)
    5) минимизирован повторный захват одного и того же контента.
     
    Разница на практике. В следующей строке вашего примера:

    Цитата:
    c    [m1]2. [p]пренебр.[/p] [trn]к[']о[/']кни, весёлый и не очень грамотный лондонец[/trn][/m]

    происходит закономерный фейл. По результатам дебаггера RegexBuddy, из позиции начала строки, ваша регулярка делает 199 шагов, прежде чем зафейлиться. Моя - 10 :)
    На совпадающих строках производительность сопоставима, но моя быстрее где-то на 5-8% (это чисто по кол-ву шагов, не принимая во внимание наличие условия и захват групп).
     
    Возвращаясь к первоначально поставленной задаче. Правильная регулярка для её решения:

    Код:
    ^c(?:(?!\[m1\]).)*$

     
    ------------------------
     
    gerxer
    Работает. Словарь Apresyan. Регулярка  

    Код:
    ^a(?:(?!la).)*$

    фильтрует все заголовки, типа a la carte, a la francaise, оставляя только заголовки начинающиеся на a.
     
    ------------------------
     
    YuS_2

    Цитата:
    Правильнее было бы так:

    Но почему правильнее?.. С точки зрения функционала - это то же самое (те же яйца, как говорится :)). Но я придерживаюсь паттерна, который присутствует в документации JGSoft. Там именно так. Да и короче.

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 13:07 04-02-2019 | Исправлено: Romul81, 13:07 04-02-2019
    Jonmey

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

    Цитата:
    Ваша регулярка не делает главного - не отвечает заданному условию и находит не те совпадающие строки, что нужно.

    Задача решена от обратного. Если вы до сих пор не поняли.
    То есть, регеэкспы оставляют искомые строки при удалении ненужных.
    Если кому-то нужно оставить обратное - включает сбор данных.
    Мне было интересен именно этот путь и я его представил.
    И этого достаточно, чтобы понять направление мысли или внести необходимые коррективы под свои собственные хотелки. Квартиру под ключ никому не общал. Собственно все.
    Да, и ваш тезис

    Цитата:
    Они просто нерабочие.

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

    Всего записей: 1305 | Зарегистр. 17-01-2011 | Отправлено: 13:29 04-02-2019 | Исправлено: Jonmey, 13:39 04-02-2019
    Romul81



    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Jonmey

    Цитата:
    Задача решена от обратного. Если вы до сих пор не поняли.  

    Ну да, естественно, конечно, я не понял.
     
    Я люблю иногда подискутировать. Но мне интересна предметная дискуссия. В данном случае её нет. Вместо того, чтоб вникнуть в моё подробное описание вопроса (написанное, заметьте, в очень корректном тоне), вы предпочли впасть в борцунство, пытаясь сделать хорошую мину при плохой игре.

    Цитата:
    ошибочен, что продемонстрировано на предыдущем скрине.  

    Объясняю своё утверждение, которое вас так задело. Нерабочие по следующим причинам:
    1) диалекто-зависимые. Работают только в Perl/PCRE и JGsoft. Конкретно в программе, для которой спрашивал gerxer не работают.
    2) даже там где работают, не отвечают заданным условиям, находя лишние совпадения, по причине ошибочной логики. К тому же захватывают т.н. zero length match на отфильтрованных строках, что не есть гут.
     
    И всё это не имеет отношения к моим личным "хотелкам", не надо переносить на других свои личные комплексы

    Всего записей: 1326 | Зарегистр. 03-03-2008 | Отправлено: 14:06 04-02-2019
    Jonmey

    Advanced Member
    Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
    Romul81
    По делу есть что или вы только потрепаться? Если последнее, то во Флейм или ПМ.

    Всего записей: 1305 | Зарегистр. 17-01-2011 | Отправлено: 14:09 04-02-2019 | Исправлено: Jonmey, 14:13 04-02-2019
    Открыть новую тему     Написать ответ в эту тему

    Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

    Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Регулярные выражения


    Реклама на форуме Ru.Board.

    Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
    Modified by Ru.B0ard
    © Ru.B0ard 2000-2024

    BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

    Рейтинг.ru