Строка RegEx preg_replace

Мне нужно выполнить «найти и заменить» около 45 тыс. строк файла CSV, а затем поместить это в базу данных.

Я подумал, что смогу сделать это с помощью PHP и preg_replace, но не могу понять выражение...

Строки состоят из одного поля и все имеют следующий формат:

"./1/024/9780310320241/SPSTANDARD.9780310320241.jpg" или "./t/fla/8204909_flat/SPSTANDARD.8204909_flat.jpg"

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

Я придумал следующее, что кажется правильным, однако я открыто заявляю, что совсем не знаю о регулярных выражениях, это немного ново для меня! Я, наверное, наделал кучу глупых ошибок...

$pattern = "/^(\.\/[0-9a-zA-Z]{1}\/[0-9a-zA-Z]{3}\/[0-9a-zA-Z]{1,13}\/)$/";
$new = preg_replace($pattern, " ", $i);

В любом случае любая помощь приветствуется!

Спасибо, Фил


person phil    schedule 08.09.2009    source источник
comment
имена файлов jpg всегда имеют длину 13 символов?   -  person stefita    schedule 08.09.2009


Ответы (5)


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

'#^.*/#' 

Это просто соответствует всему, включая последнюю косую черту, что и сделало бы ваше регулярное выражение, если бы не этот мошеннический «$», о котором все говорят. Если есть другие строки в других форматах, которые вы хотите оставить в покое, это регулярное выражение, вероятно, удовлетворит ваши потребности:

'#^\./\w/\w{3}/\w{1,13}/#"

Обратите внимание, как я изменил разделитель регулярных выражений с '/' на '#', поэтому мне не нужно экранировать косые черты внутри. В качестве разделителей можно использовать практически любые знаки пунктуации (но, конечно, они оба должны быть одинаковыми).

person Alan Moore    schedule 08.09.2009
comment
Это намного чище, все строки должны быть в одном формате, но я не хочу этого предполагать. Я использовал вторую версию, так как она проще и чище, просто нужно было изменить на [\w-] для учета дефисов. Правильно ли я предполагаю, что \w - это буквенно-цифровые символы и символы подчеркивания? - person phil; 08.09.2009
comment
Да, \w совпадает с [A-Za-z0-9_]. В некоторых других вариантах регулярных выражений он также соответствует буквам с диакритическими знаками, а также буквам и цифрам из других систем письменности, но \w в PHP ограничен ASCII. - person Alan Moore; 08.09.2009

Единственная ошибка, которую я обнаруживаю, — это якорь для конца строки $, который следует удалить. И в вашем выражении также отсутствует символ _:

/^(\.\/[0-9a-zA-Z]{1}\/[0-9a-zA-Z]{3}\/[0-9a-zA-Z_]{1,13}\/)/

Более общим шаблоном было бы просто исключить /:

/^(\.\/[^\/]{1}\/[^\/]{3}\/[^\/]{1,13}\/)/
person Gumbo    schedule 08.09.2009
comment
Спасибо, теперь работает нормально! Приятно знать, что я сделал только одну крошечную ошибку! Однако второй пример выдает ошибку! Предупреждение: preg_replace() [function.preg-replace]: Неизвестный модификатор ']' Однако первый работает нормально. Спасибо еще раз! - person phil; 08.09.2009

Вы должны использовать встроенный синтаксический анализатор PHP для извлечения значений из CSV, прежде чем сопоставлять какие-либо шаблоны.

person soulmerge    schedule 08.09.2009
comment
Значения не заключены в кавычки в обрабатываемом файле. Чисто из образовательного интереса, как мне выполнить ту же замену шаблона без использования регулярного выражения? Боюсь, я не знаю, с чего начать. - person phil; 08.09.2009
comment
Извините, я недостаточно внимательно прочитал ваш вопрос. Я предполагаю, что вы должны использовать здесь регулярные выражения, но я бы сначала извлек значения из csv, а затем применил RE. - person soulmerge; 08.09.2009

$ означает конец строки. Таким образом, ваш шаблон будет соответствовать ./1/024/9780310320241/ и ./t/fla/8204909_flat/, если они будут одни на своей линии. Удалите $, и он будет соответствовать первым четырем частям вашей строки, заменив их пробелом.

person Olivier 'Ölbaum' Scherler    schedule 08.09.2009

$pattern = "/(\.\/[0-9a-z]{1}\/[0-9a-z]{3}\/[0-9a-z\_]+\.(jpg|bmp|jpeg|png))\n/is";

Я только что увидел, что строка вашего примера не заканчивается на /, поэтому, возможно, вам следует удалить ее из шаблона в конце. Также подчеркивание используется в имени файла и должно быть в классе символов.

person stefita    schedule 08.09.2009