-2

I have a string:

$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';

now i need to get substring for setted language.

$placeholder = '{:en}';
$lang_content =  preg_replace('/(.*)'.preg_quote($placeholder).'(.*)'.preg_quote('{:}').'(.*)/sm', '\2', $str);

in case of value for placeholder {:en} i get Helo world as value for $lang_content, it works fine, but in case {:de} i get Hallo Welt{:}{:en}Helo world. How can it be fixed? thanx!

Mohammad
  • 21,175
  • 15
  • 55
  • 84
spoff
  • 13
  • 4

2 Answers2

0

You need to make the regex lazy by adding a ? in the second capture.

$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';

$placeholder = '{:de}';
$lang_content =  preg_replace('/(.*)'.preg_quote($placeholder).'(.*?)'.preg_quote('{:}').'(.*)/sm', '\2', $str);

echo $lang_content; // Hallo Welt

https://3v4l.org/m6AGF


An optional method would be to use preg_match to get an associative array.

$str = '{:de}Hallo Welt{:}{:en}Helo world{:}';

preg_match_all("/\{:(.*?)}(.*?)\{/", $str, $matches);
$matches = array_combine($matches[1], $matches[2]);

var_dump($matches);
echo $matches["de"]; // Hallo Welt

https://3v4l.org/ELB2B

Andreas
  • 23,610
  • 6
  • 30
  • 62
0

With the Ungreedy flag (U).

You can update the flags at the end of your regex from /sm to /smU for the result to stop at the next occurrence of {:} in the string and not at the last one.

If the string is to contain several occurrences, maybe you can also add the global (g) flag so the regex doesn't stop after the first one.

You can test it here: https://regex101.com/r/4XSPoz/3

By the way, it seems that your are using preg_replace as a way to find a substring and don't actually need to replace it in the result, maybe you should use preg_match instead.

Divarrek
  • 325
  • 3
  • 11