Добрый день, Сегодня столкнулся, как мне кажется, с совершенно идиотской проблемой, но чувствую что начал "пробуксовывать"... Топик можно одновременно отнести к базам регуляркам и блондинкам, поэтому вычислив среднее решил запостить сюда Суть следующая: 1. Windows Server 2000 2. Адреса вида C:\test\ - обратите внимание на слеши 3. Адреса нужно записать в базу. 4. Нужно делать выборку из базы по LIKE А теперь попорядку: Очень хочется писать адреса в базу "как есть", то есть именно C:\test\, а не c:/test/ или /test/ или еще как. Допустим в базе имеется три записи в колонке path: c:\test\ c:\test\1\ c:\test\test\ вставка нормально проходит после обработки mysql_escape_string(); Далее нам нужно переименовать C:\test\ следовательно и все под дирректории, то есть C:\test\1\ и C:\test\test\ Для этого нужно сделать выборку записей, где теоретически в WHERE можем записать, то же что и при вставке: Код (Text): "SELECT path FROM table WHERE path LIKE '".mysql_escape_string($path)."%' GROUP BY path" Тут баг №1 при $path == 'C:\test\'; количество записей в результате = 0 при этом запрос Код (Text): "SELECT path FROM table WHERE path = '".mysql_escape_string($path)."' GROUP BY path" вернет 1 запись. Объясняется он тем что, \test обрабатывается как \t и строка est Следовательно нам нужно сделать экранирование этого слеша: после mysql_escape_string адрес уже имеет вид C:\\test\\, теперь нам нужно еще его преобразовать в C:\\\\test\\, и так подставлять по два слеша перед каждым символом после слеша. Собственно место, где я начал подбуксовывать - до запроса делаем обработку: $path = preg_replace ("'(\\)([^\\]+)'", '\\1\\1\\2', mysql_escape_path($path)); По логике регулярка должна найти \ после которого стоит не \ и дописать еще один \. Вопрос 1: [^\\]+ - конструкция не работает, как она будет работать? Вопрос 2: Более человечески можно записать в '\\1\\1\\2' вместо \\1 просто \ ? Вариантов для обхода этих вопросов масса, но хочется пройти по прямой, потому и задаю этот вопрос. С уважением, vb
Чтобы не извращаться со слешами сделал так: Код (Text): SELECT path FROM table WHERE LOCATE('C:\\test\\', path) = 1 GROUP BY path то есть просто $path = mysql_escape_string($path);
Нет, по ссылке повторяют то что было написано во введении, причем то есть str_replace в сочетании c addslashes - лишнее. У меня проблема немного глубже - в получении строки вида: C:\\\\test\\\\vb\\ бррр, вернее это не проблема, меня уже интересуют ответы на 2-а вопроса: Собственно расписал все так наврное больше от желания поделиться инфой нежели узнать ответ на основной ответ о экранировании.
кажется, так: PHP: <?php $path = 'C:\\test\\vb\\'; echo preg_replace('~(\\\\)([^\\\\])~', '\\\\\\1\\1\\2', mysql_escape_string($path)); ?> но лучше бы здесь подошел способ с str_replace.
simpson, спасибо, из Вашего ответа вывел ответ и на второй вопрос : PHP: <?php $path = 'C:\\test\\vb\\'; echo preg_replace('~\\\\([^\\\\])~', '\\\\\\\\\\\\\\1', mysql_escape_string($path)); ?> ИМХО жесть
отлично. только разберём этот случай по пунктам, для возможных будущих читателей. Заблуждение номер 1. Поскольку в документации ясно написано, что в строках, которые подставляются в оператор LIKE должны быть удвоены слеши. Отсюда выходит, что Это на самом деле не баг, а фича. И, следовательно, задача - это заблуждение номер 2. Поскольку преобразовывать надо в C:\\\\test\\\\, то регулярка, как следствие, не нужна. Что и требовалось доказать.
Мой код который я вам пытался покозать записывает в базу c:\test После чего делали запрос SQL-запрос: SELECT * FROM `table` WHERE `path` LIKE 'c:\\\\test%' LIMIT 0 , 30 И данный запрос прекрасно сработал – так почему на данный код была такая реакция