Reputation: 61
I have string in PHP
$str = '1,"4052","B00K6ED81S",,"Bottle, white - 6,5 l, WENKO","Good design!","Bottle, white 6,5 l, WENKO",,,"item","23",23,"23",23,31.22,31.22,,1,,,,0,8,"4",,0,,0,0,,0,,0,0,,
There are comma delimiters. Somewhere are empty fields, somewhere fields with quotes (as names of products). The problem is in replacing delimiters to semicolon, but don't touch commas in products names. I need this:
$str_replace = '1;"4052";"B00K6ED81S";;"Bottle, white - 6,5 l, WENKO";"Good design!";"Bottle, white 6,5 l, WENKO";;;"item";"23";23;"23";23;31.22;31.22;;1;;;;0;8;"4";;0;;0;0;;0;;0;0;;';
I tried this code:
$str = '1,"4052","B00K6ED81S",,"Bottle, white - 6,5 l, WENKO","Good design!","Bottle, white 6,5 l, WENKO",,,"item","23",23,"23",23,31.22,31.22,,1,,,,0,8,"4",,0,,0,0,,0,,0,0,,';
$str = preg_replace('/,,/', ',~~~,', $str);
$str = preg_replace('/,,/', ',~~~,', $str);
$pattern = '/(?<=\d),|(?<="),|~~~,/';
$str = preg_replace($pattern, ';', $str);
Result:
1;"4052";"B00K6ED81S";;"Bottle, white - 6;5 l, WENKO";"Good design!";"Bottle, white 6;5 l, WENKO";;;"item";"23";23;"23";23;31.22;31.22;;1;;;;0;8;"4";;0;;0;0;;0;;0;0;;
In the product's name comma's replacing to semicolon too:
"Bottle, white - 6;5 l, WENKO"
How I can correct $pattern
to get result I need?
Upvotes: 1
Views: 257
Reputation: 23958
I just wanted to try and make a code that can do it the old fashioned way.
It finds the " and depending on if it's between them or outside of them it does or does not the replace.
$str = '1,"4052","B00K6ED81S",,"Bottle, white - 6,5 l, WENKO","Good design!","Bottle, white 6,5 l, WENKO",,,"item","23",23,"23",23,31.22,31.22,,1,,,,0,8,"4",,0,,0,0,,0,,0,0,0';
$pos=1; // set $pos to make sure while loop does not end directly.
$newstr = "";
$prevPos = 0;
if($str[0]=='"') $str = " " .$str; // add space if the first char is a "
$skip = false; // flag to know if replace should be done or not
while($pos != false){
$pos = strpos($str, '"', $prevPos); // find " in string after prevPos
$part = substr($str, $prevPos, $pos+1-$prevPos); // substring the part (first time it runs it will be '1,"' then '4052"')
if($skip){ // if it's between two " (a string) skip the replace
//echo "skip " . $part . "\n";
$skip =!$skip; // change the flag
$newstr .= $part;
}else{ // if it's not in a string do the replace on the $part
//echo "!skip " . $part . "\n";
$newstr .= str_replace(",", ";", $part);
$skip =!$skip; // change the flag.
}
$prevPos = $pos+1; // set new $prevPos
}
// if the loop ends and there is no more " in the string we need to replace , to ; on the rest of the string.
// we know the loop ended at strlen($newstr), so that is the $part.
if($pos<strlen($str)) $newstr .= str_replace(",", ";", substr($str, strlen($newstr)));
echo $str . "\n";
echo $newstr;
https://3v4l.org/CnSh8
It actually performs quite well. Better than I expected beeing a loop and all the if's and string operations.
EDIT; Noticed that it didn't work if the first item is a string. I add a space just to make sure the flag comes in the correct order.
This can easily be trimmed with trim().
https://3v4l.org/hNLAF
Upvotes: 1