Ответы пользователя по тегу Регулярные выражения
  • Как ускорить выполнение preg_replace (в массиве 100 паттернов)?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Так себе идея обрабатывать теги регулярками, но...
    Пощупать вашу проблему я не могу ввиду страшной аллергии к ПХП.
    Могу предложить ряд оптимизацией обобщенного характера.
    1. Проанализировать регулярки, найти зависимости и "скомпилировать" их в одну регулярку или небольшую группу из нескольких. Обрабатывать регулярки можно эвентуально. То есть дополнительно анализировать матчи программно и в зависимости от контекста подставлять соответствующую замену. Ещё можно пир компиляции регулярок в одну поименовать группы уникально так, чтобы по имени проматченной группы можно было найти нужную замену в словаре замен.
    2. Если замены более-менее однотипные, например одни теги заменяются на другие, то можно вообще построить общую универсальную простую регулярку на тег, а программно смотреть по словарю чему соответствует матч и делать нужную замену.

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

    Вообще, система, построенная на высокочастотной обработке большого текста сотней регулярок явно спроектирована как-то неправильно. Как выше сказали, наверняка эту проблему надо было решать в другом месте.
    Ответ написан
    Комментировать
  • Как это закодить?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст
    reg_expr - это не словарь, а грамматика, описывающая некое выражение.
    По русски читается примерно как:
    Регексп - ЭТО:
    ЛИБО Атом
    ЛИБО ОператорИли(с двумя аргументами: первый - Регексп; второй - тоже Регексп)
    ЛИБО ОператорТочка(с двумя аргументами: первый - Регексп; второй - тоже Регексп)
    ЛИБО ОператорЗвёздочка(с одним аргументом, который Регексп).

    Ниже важное дополнение:
    Priority of the key is following ‘*’ > ‘.’ > ‘|’
    ‘*’ is postfix
    ‘.’ and ‘|’ are left associative

    Это значит, что у ОператораЗвёздочка самый высокий приоритет, потом идёт ОператорТочка, потом ОператорИли.
    ОператорЗвёздочка постфиксный, то есть применяется после своего единственного аргумента.
    ОператорТочка и ОператорИли - лево-ассоциативные.

    Похоже автору вопроса нужно написать регулярное выражение, которое будет матчиться со строкой, соответствующей описанной грамматике.
    Дальше может быть только решение задачи, а автор о нём не спрашивал, а лишь спросил с чего начать.
    Не буду ломать ему удовольствие и спойлерить результат=)
    Ответ написан
    Комментировать
  • Как ограничить диапазон двузначных чисел в нетривиальном регулярном выражении?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Вы можете описать регуляркой число от 1-16 так: (1[0-6])|([1-9])
    Но регекспы не предназначены для условной фильтрации по выражениям.
    Обычно они определяют только синтаксис и разделяют текст на группы, которые потом нужно преобразовывать к типам и проверять.
    Если приспичило всё-таки, используйте мой вариант описания числа 1-16, но завтра вам потребуется определять четность, а послезавтра потребуется, чтобы правая граница интервала была вдвое больше левой... Надо где-то остановиться и где именно -- решать вам.

    Вот в применении к вашему случаю:
    ^((1[0-6]|[1-9])(-(1[0-6]|[1-9]))?)(,((1[0-6]|[1-9])(-(1[0-6]|[1-9]))?))*$

    Можете даже потестировать
    Ответ написан
    2 комментария
  • Почему не проходит валидацие через regex?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    (SM-\d+ - \[(Infrastructure|FIX)\]) - \S.*
    https://regex101.com/r/FAaQ5b/1

    Вообще вы не предоставили достаточно кейсов для нормального ответа.
    Может вам такое больше подойдёт:
    (SM-\d+ - )?(\[(Infrastructure|FIX)\] - )?\s*.*
    Тут тикет-id необязателен и тип коммита необязателен и в крайнес влучае проматчится хотя бы текст.
    Хотя если валидатор, то вы, наверно, хотите. чтобы все коммиты были к тикетам привязаны и отмечены типом.
    Ответ написан
  • При разделении на предложения как определить предложение, которое не заканчивается на какой-либо знак препинания?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    /[^\.\!\?!。?,,::;;]+([\.\!\?!。?,,::;;]+|$)/g
    Ответ написан
    Комментировать
  • Не понять регулярку?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Эта регулярка будет совпадать с текстом, начинающимся с открывающейся квадратной скобки, состоящий из одного или более любых символов вплоть до ближайшей закрывающей скобки.
    Вопросик нужен, чтобы плюсик был нежадным, то есть не сожрал закрывающуюся скобку тоже. По умолчанию + и * жадные, то есть сожрут как можно больше символов, но чтобы в целом выражение сматчилось.
    Если ваш текст "12[34]56[78]90", то жадная регулярка (без вопросика) найдёт "[34]56[78]", а не жадная найдёт "[34]" и "[78]".
    Ответ написан
    Комментировать
  • Как с помощью regexp заменить 5 найденый элемент а не все?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Replace:(.*?</a>){5}
    To: $0<a href="url_here">text</a>
    Ответ написан
    1 комментарий
  • Как проверить регуляркой значение инпута которое будет идти после скобки?

    trapwalker
    @trapwalker
    Программист, энтузиаст
    Есть замечательный инструмент для отладки регекспов: https://regex101.com/
    Вот пример регулярки, которая решает вашу проблему:
    .*\((\d+)
    Первая группа даст вам ваше число.
    Подробнее: здесь жадно пропускаются все символы до скобки, за которой есть хотя бы одна цифра. Все цифры после этой скобки собираются в группу 1.
    Этот же сайтик позволяет сгенерировать код примера на нескольких языках:
    const regex = /.*\((\d+)/gm;
    const str = `8(354)1234
    8(354 456)789
    `;
    let m;
    
    while ((m = regex.exec(str)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        
        // The result can be accessed through the `m`-variable.
        m.forEach((match, groupIndex) => {
            console.log(`Found match, group ${groupIndex}: ${match}`);
        });
    }
    Ответ написан
  • Почему «срабатывает» выражение?

    trapwalker
    @trapwalker Куратор тега Python
    Программист, энтузиаст

    У вас лишний обратный слеш а авражении "\" и строка не сырая. Короче, правильно леоать так:
    re.match(r'/link/abcd(/.*)?$','/link/abcd/')
    Хвостовой слеш не обязателен, но если он есть, после него допускаются любые символы в любом количестве, в том числе нулевом.

    Ответ написан
    Комментировать