Home > front end >  Use regex to quote the name in name-value pair of a list of pairs
Use regex to quote the name in name-value pair of a list of pairs

Time:09-23

I am trying to put quotes around the names of name-value pairs separated by commas. I use preg_replace and regex to achieve that. However, my pattern is not working properly.

$str="f1=1,f2='2',f3='a',f4=4,f5='5'";
$newstr=Preg_replace(/'(?.[^=] )'/,"'$1'",$str);

I expected $newstr to come out like so: 'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5' But it doesn't and the qoutes don't contain the name. What should the pattern be and how can I use the comma to get all of them correctly?

CodePudding user response:

There are a few issues with your attempt:

  • PHP does not have a regex-literal syntax as in JavaScript, so starting the regex value with a forward slash is a syntax error. It should be a string, so start with a quote. Maybe you accidently swapped the slash and quote at the start and the end.

  • (?. is not valid. Maybe you intended (?:, but then there is no capture group and $1 is not a valid back reference. To have the capture group, you should not have (?., but just (.

  • [^=] could include substrings like 1,f2. There should be logic to not start matching while still inside a value (whether quoted or not).

I would suggest a regex where you match both parts around the = (both key and value), and then in the replacement, just reproduce the second part without change. This will ensure you don't accidently use anything in the value side for wrapping in quotes:

$newstr = preg_replace("/([^,=] )=('[^']*'|[^,]*)/","'$1'=$2",$str);

CodePudding user response:

Basically, match beginning of line or a comma (with negative capture) and then capture everything until a =

$reg = "/(?<=^|,)([^=] )/";
$str = "f1=1,f2='2',f3='a',f4=4,f5='5'";
print_r(preg_replace($reg, "'$1'", $str));
// output:
// 'f1'=1,'f2'='2','f3'='a','f4'=4,'f5'='5'

CodePudding user response:

This will also work, a different approach, but assuming there will be no comma in the values or names except the separators..

$newstr = preg_replace("/(.)(?==)|(?<=,|^)(.)/", "$1'$2", $str);

But I believe string and simple array operations will be faster as the regex is really getting complex and there are so many steps to get the characters.. Here is the same output but with array functions only.

$newstr = implode(",", array_map(function($element){ return "'". implode("'=", explode("=", $element)); }, explode(",", $str)));

RegEx is not always fast than string or array operations, but yes it can do complex things with little bit of code.

  • Related