rtom
rtom

Reputation: 219

Replace specific character inbetween brackets

I want to replace , with :character that is located in between []. So [Hello, as] a, booby will change to [Hello: as] a, booby. I cannot figure out how to match the comma within brackets, I can match the word inside brackets with \[(.*)\] but I don't know how to pick the comma from there.

Also if I get [[Hello, as] a, booby], then I also want to change only the first comma. I tried to use * or + but it doesn't work.

I need this

[["Sender", "[email protected]"], ["Date", "Fri, 09 Jun 2017 13:29:22 +0000"]]

To became this

[["Sender": "[email protected]"], ["Date": "Fri, 09 Jun 2017 13:29:22 +0000"]]

I wanted to use preg_replace but I It was not the right solution.

preg_replace("/(\[[^],]*),/U" , ':', $arr) 

returns

": [email protected]"], : "Fri, 09 Jun 2017 13:29:22 +0000"]

Upvotes: 0

Views: 98

Answers (3)

mickmackusa
mickmackusa

Reputation: 48070

This seems as simple as I can make it: (Demo Link)

(?<="),

It makes some assumptions about your nested psuedo array values.

PHP Implementation:

$in='[["Sender", "[email protected]"], ["Date", "Fri, 09 Jun 2017 13:29:22 +0000"], ["Name", "Dude"]]';
echo preg_replace('/(?<="),/',':',$in);

Output:

[["Sender": "[email protected]"], ["Date": "Fri, 09 Jun 2017 13:29:22 +0000"], ["Name": "Dude"]]

If this doesn't suit your actual strings, please provide a string where my pattern fails, so that I can adjust it. Extending the pattern to ensure that that comma follows the quoted "key" can be done like this: "[^"]+"\K, ...at a slightly higher step cost (but still not bad).

Upvotes: 1

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89639

You can use a \G based pattern:

$str = preg_replace('~(?:\G(?!\A)|\[(?=[^][]*]))[^][,]*\K,~', ':', $str);

This kind of pattern starts with 2 subpatterns in an alternation:

  • \[(?=[^][]*]) that searches a [ followed by a ] without other brackets between them.
  • \G(?!\A) that matches at the position after a previous match

Then, in the two cases [^][,]*\K, reaches the next , that can only be between [ and ].

But since you also need to skip commas between double quotes, you have to match double quotes parts before an eventual comma. To do that, change [^][,]* to [^][",]*(?:"[^"\\]*(?s:\\.[^"\\]*)*"[^][",]*)*+

$str = preg_replace('~(?:\G(?!\A)|\[(?=[^][]*]))[^][",]*+(?:"[^"\\\\]*(?s:\\\\.[^"\\\\]*)*"[^][",]*)*+\K,~', ':', $str);

demo

Upvotes: 0

lcHatter
lcHatter

Reputation: 120

Try grouping everything before and after the comma, then put them back around the colon.

preg_replace('/(\[.*?),(.*?\])/','$1:$2',$string)

Upvotes: 0

Related Questions