2

I know this has been asked elsewhere, but I can't find the precise situation (and understand it!) so I'm hoping someone might be able to help with code here.

There's an array of changes to be made. Simplified it's:

$title = "Tom's wife is called Tomasina";

$change_to = array(
   "Tom"        => "Fred",
   "wife"       => "girlfriend",
);

$title = preg_replace_callback('(\w+)', function( $match )use( $change_to ) {
    return $array[$match[1]];
}, $title);

I'm hoping to get back "Fred's girlfriend is called Tomasina" but I'm getting all sorts of stuff back depending on how I tweak the code - none of which works!

I'm pretty certain I'm missing something blindingly obvious so I apologise if I can't see it!

Thank you!

arathra
  • 155
  • 1
  • 11

1 Answers1

1

There are several issues:

  • Use $change_to in the anonymous function, not $array
  • Use regex delimiters around the pattern (e.g. /.../, /\w+/)
  • If there is no such an item in $change_to return the match value, else, it will get removed (the check can be performed with isset($change_to[$match[0]])).

Use

$title = "Tom's wife is called Tomasina";

$change_to = array(
   "Tom"        => "Fred",
   "wife"       => "girlfriend",
);

$title = preg_replace_callback('/\w+/', function( $match ) use ( $change_to ) {
    return isset($change_to[$match[0]]) ? $change_to[$match[0]] : $match[0];
}, $title);
echo $title;
// => Fred's girlfriend is called Tomasina

See the PHP demo.

Also, if your string can contain any Unicode letters, use '/\w+/u' regex.

Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Almost there now! But working through this I came across another problem - even if I add the `i` flag to the pattern e.g. `/\w+/i` it will not go case insensitive and in the above example an array item of `"tom" => "Fred"` will not be found in the original string. – arathra Nov 23 '18 at 19:28
  • @arathra `\w` does not need case insensitive flag, it match both upper- and lowercase chars. Since you are just matching any sequence of 1 or more word chars, you cannot control case sensitivity through regex, you need to do that yourself. I have just [googled a possible workaround](https://stackoverflow.com/a/4240019/3832970). A regex approach will depend on 1) the size of `$change_to`, 2) If keys contain whitespaces, 3) if keys can contain special chars and can start/end with them. – Wiktor Stribiżew Nov 23 '18 at 19:32
  • Once again I have to thank you, Wiktor! I spent hours trying to find the solution, moving in the direction of changing the array first, but couldn't find the right way till you linked to array_change_key_case. Cheers! – arathra Nov 24 '18 at 09:31