SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 16.08.2012 10:29:12

ArmanZak
Участник
Зарегистрирован: 19.03.2011
Сообщений: 17

Вопрос про регулярных выражений

Привет всем.
у меня вот такая проблемма
в базе хранится путь к некоторому файлу в виде \path\to\file\filename.ext, таблица в виде table(id, path)
и в php есть переменная
$path = '\path\to\file\';
нужно составить запрос который возвратиль бы все id файлов находашиеся в папке $path.

сам составил такой запрос
$sqlquery =  "select `id` from `table` where `path` regexp '".$path."[/w/d]+[[.period.]]/w+' "


но не работает(нет никаких совпадений, хотя есть)

Неактивен

 

#2 16.08.2012 19:48:19

LazY
_cмельчак
MySQL Authorized Developer and DBA
Зарегистрирован: 02.04.2007
Сообщений: 849

Re: Вопрос про регулярных выражений

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

Рассмотрим на примере строки '\path\to\file'.
Последовательность \p с точки зрения POSIX регулярных выражений специальной не является, чего нельзя сказать о \t (табуляция) и \f (что-то еще, не помню).
Поэтому перед применением шаблона все обратные слэши нужно экранировать (возможно, нужно экранировать что-то еще - по-хорошему, должна была быть функция, которая экранирует в строке все спецсимволы POSIX-шаблонов, но её нет, поэтому экранируем вручную те, которые вспомним).

Но обратный слэш является специальным символом не только в POSIX regexp, но и в самой MySQL. Поэтому когда она увидит два подряд идущих обратных слэша, она превратит их в один, и в шаблон снова попадёт только один.
Поэтому перед передачей строки в запрос нужно не только добавить по лишнему слэшу, но и провести экранирование в MySQL - для этого есть функция mysql_real_escape_string().

В итоге запрос должен выглядеть как-то так:

$regex = '^'
       . $path
       . '[^\]+[[.period.]][[:alpha:]]+' ;

$regex_escaped = mysql_real_escape_string(
        str_replace(
            '\\',    // в PHP обратный слэш - тоже специальный символ
            '\\\\', // поэтому приходится писать в удвоенных количествах
            $regex
        )
    );

$sqlquery =  "
    SELECT `id`
    FROM `table`
    WHERE `path` REGEXP '$regex_escaped'
    "
;
 

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

Неактивен

 

#3 17.08.2012 10:25:16

ArmanZak
Участник
Зарегистрирован: 19.03.2011
Сообщений: 17

Re: Вопрос про регулярных выражений

спасибо помогло,
только с
$regex = '^'
        . $path
        . '[[:alnum:]]+[[.period.]][[:alpha:]]+' ;

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson