#php #regex
#php #регулярное выражение
Вопрос:
Я хочу заменить каждую двойную кавычку в записи csv, подлежащей замене, каким-либо другим символом, скажем, @ # @, сохраняя внутренние двойные кавычки неизменными.
например, рассмотрим следующую запись
123453,"The NFL is promoting the importance of annual mammogram screenings for women over 40 in the prevention of breast cancer through their "A Crucial Catch" campaign.","Pittsburgh Steelers","NFL"
из этой записи я хочу заменить двойные кавычки на @#@ в начале и конце каждого поля, чтобы оно стало
123453,@#@The NFL is promoting the importance of annual mammogram screenings for women over 40 in the prevention of breast cancer through their "A Crucial Catch" campaign.@#@,@#@Pittsburgh Steelers@#@,@#@NFL@#@
пожалуйста, обратите внимание, что «Критическая ошибка» не изменилась, поскольку она находится внутри уже запущенных двойных кавычек
Комментарии:
1. Принимаю ваши недавние вопросы!
2. Да, например, эта строка:
"a",1,"c"
— как синтаксическому анализатору узнать, являются ли они строкой, числом и string или просто одной длинной строкой, содержащей внутренние двойные кавычки и несколько запятых? Я думаю, вы не можете делать то, что хотите, без хотя бы некоторого экранирования.
Ответ №1:
Я поддержал комментарий, потому что вы должны принять ответы на свои вопросы, в которых есть хорошие ответы (я видел там пару)… но вот возможное решение:
<?php
$orig = '123453,"The NFL is promoting the importance of annual mammogram screenings for women over 40 in the prevention of breast cancer through their "A Crucial Catch" campaign.","Pittsburgh Steelers","NFL"';
$cols = explode(',', $orig);
function replace_end_quotes($val) {
return preg_replace('#(^"|"$)#', "@#@", $val);
}
echo implode(",", array_map("replace_end_quotes", $cols));
Как упоминалось в комментарии @socha23, если в одном из полей есть запятая, мое решение не будет работать. Однако, если ваша строка выше была фактически отформатирована как допустимые данные CSV, то использование чего-то вроде str_getcsv вместо explode сделало бы свое дело.
Комментарии:
1. да, для csv я использую функцию str_getcsv, файл, о котором я упоминал, представляет собой текстовый файл с записями, разделенными запятыми, а не CSV-файл starndart
2. Я делаю все это, действительно, между одним из полей появляется запятая
Ответ №2:
Вы могли бы выполнить поиск по
"(?=,|$)|(?<=^|,)"
и замените это на @#@
. Это регулярное выражение ищет кавычку, перед которой или за которой стоит запятая (или начало / конец строки).
Итак, в PHP:
$result = preg_replace('/"(?=,|$)|(?<=^|,)"/', '@#@', $subject);
Изменения
123453,"The NFL is promoting "A Crucial Catch".","Pittsburgh Steelers","NFL"
в
123453,@#@The NFL is promoting "A Crucial Catch".@#@,@#@Pittsburgh Steelers@#@,@#@NFL@#@
Ответ №3:
Почему бы не выполнить цикл по файлу и создать строку, которая реконструирует это.
Хотя это и не очень эффективно, вы могли бы попробовать…
$out = "";
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$arr = array();
for ($i = 0; $i < count($data); $i ) {
if (!ctype_digit($data[$i])) {
$data[$i] = '@#@' . $data[$i] . '@#@';
}
$arr[] = $data[$i];
}
$out .= implode("", $arr) . "n";
}
fclose($handle);
}
// Write $out to file or whatever