Каких специальных символов нужно оставить в регулярных выражениях?

Я написал эту небольшую функцию несколько лет назад:

function sqlvprintf($query, $args)
{
    global $DB_LINK;
    $ctr = 0;
    ensureConnection(); // Connect to database if not connected already.
    $values = array();
    foreach ($args as $value)
    {
        if (is_string($value))
        {
            $value = "'" . mysqli_real_escape_string($DB_LINK, $value) . "'";
        }
        else if (is_null($value))
        {
            $value = 'NULL';
        }
        else if (!is_int($value) && !is_float($value))
        {
            die('Only numeric, string, array and NULL arguments allowed in a query. Argument '.($ctr+1).' is not a basic type, it\'s type is '. gettype($value). '.');
        }
        $values[] = $value;
        $ctr++;
    }
    $query = preg_replace_callback(
        '/{(\\d+)}/', 
        function($match) use ($values)
        {
            if (isset($values[$match[1]]))
            {
                return $values[$match[1]];
            }
            else
            {
                return $match[0];
            }
        },
        $query
    );
    return $query;
}

function runEscapedQuery($preparedQuery /*, ...*/)
{
    $params = array_slice(func_get_args(), 1);
    $results = runQuery(sqlvprintf($preparedQuery, $params)); // Run query and fetch results.   
    return $results;
}

Это позволяет запускать операторы в однострочном C # -ish String.Format, например:

runEscapedQuery("INSERT INTO Whatever (id, foo, bar) VALUES ({0}, {1}, {2})", $numericVar, $stringVar1, $stringVar2);

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

ОБНОВЛЕНИЕ БЕЗОПАСНОСТИ: предыдущая версия str_replace разрешала инъекции, добавляя токены {#} в пользовательские данные. Эта версия preg_replace_callback не вызывает проблем, если замена содержит эти токены.

372
задан Mechanical snail 1 October 2011 в 21:03
поделиться

7 ответов

Какие символы Вы должны и из которого Вы не должны выходить, действительно зависит от regex разновидности, с которой Вы работаете.

Для PCRE и большинства других так называемых совместимых с Perl разновидностей, выходят из этих внешних классов символов:

.^$*+?()[{\|

и эти внутренние классы символов:

^-]\

Для POSIX расширенный regexes (ДО), выйдите из этих внешних классов символов (то же как PCRE):

.^$*+?()[{\|

Выход из любых других символов является ошибкой с POSIX ДО.

Внутренние классы символов, обратная косая черта является буквенным символом в регулярных выражениях POSIX. Вы не можете использовать его для выхода из чего-либо. Необходимо использовать "умное размещение", если Вы хотите включать метасимволы класса символов как литералы. Поместите ^ где угодно кроме в запуске] в запуске, и - в запуске или конце класса символов для соответствия им буквально, например:

[]^-]

В основных регулярных выражениях (BRE) POSIX, это метасимволы, из которых необходимо выйти для подавления их значения:

.^$*[\

круглые скобки Выхода и фигурные скобки в BREs дают им особое значение, которое их незавершенные версии имеют в EREs. Некоторые реализации (например, GNU) также дают особое значение другим символам, когда оставлено, такой как \? и +. Выход из символа кроме $.^* () {} обычно является ошибкой с BREs.

Внутренние классы символов, BREs следуют тому же правилу как EREs.

, Если все это заставляет Вашу голову кружиться, захватите копию RegexBuddy. На вкладке Create нажмите Insert Token, и затем Литерал. RegexBuddy добавит Escape по мере необходимости.

347
ответ дан Jonathan Leffler 23 November 2019 в 00:04
поделиться

К сожалению, действительно нет набора набора кодов Escape, так как он варьируется на основе языка, который Вы используете.

Однако хранение страницы как Страница Инструментов Регулярного выражения или этот регулярное выражение Cheatsheet может пойти длинным путем, чтобы помочь Вам быстро фильтровать вещи.

22
ответ дан Dillie-O 23 November 2019 в 00:04
поделиться

POSIX распознает несколько изменений на регулярных выражениях - основные регулярные выражения (BRE) и расширенные регулярные выражения (ERE). И даже тогда, существуют причуды из-за исторических реализаций утилит, стандартизированных POSIX.

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

Выезд Jeff Friedl Регулярные выражения Освоения книга.

5
ответ дан Jonathan Leffler 23 November 2019 в 00:04
поделиться

Действительно, нет. существует приблизительно полуогромное количество различных regex синтаксисов; они, кажется, сводятся к Perl, EMACS/GNU и AT& T в целом, но я всегда становлюсь удивленным также.

4
ответ дан Charlie Martin 23 November 2019 в 00:04
поделиться

К сожалению, значение вещей как (и \(подкачиваются между Emacs, разрабатывают регулярные выражения и большинство других стилей. Таким образом, при попытке выйти из них, можно делать противоположность того, что Вы хотите.

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

4
ответ дан Darron 23 November 2019 в 00:04
поделиться

Иногда простой выход не возможен с символами, которые Вы перечислили. Например, использование обратной косой черты для выхода из скобки не собирается работать в левой стороне строки замены в sed, а именно,

sed -e 's/foo\(bar/something_else/'

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

sed -e 's/foo[(]bar/something_else/'

, который я нахожу работами для большинства regexp реализаций.

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

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

Вы хотели бы смотреть "на солнечную книгу шара" иначе Эффективный Perl ( санированная ссылка Amazon ), конкретно глава по регулярным выражениям, получать ощущение тогда различия в regexp типах оценки механизма.

Не все в мире PCRE!

Так или иначе, regexp's является настолько неуклюжим по сравнению с SNOBOL! Теперь , что был интересный ход программирования! Наряду с тем на Simula.

А-ч радости изучения в UNSW в последних '70-х! (-:

4
ответ дан vaxquis 23 November 2019 в 00:04
поделиться

Для ионического диалекта (Машинописный текст) необходимо удвоить наклонную черту чтобы до ствола колонны символы. Например (это должно соответствовать некоторым специальным символам):

"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

Обращают внимание на это ] [ - _ . / символы. Они должны быть двойными, разрезал. Если Вы не делаете этого, Вы собираетесь иметь ошибку типа в своем коде.

0
ответ дан 23 November 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: