Replace with callback

After replace(), you need to explicitly use one of first()/all()/only(int) methods, to express how many replacements should be done.

Callback passed to replace()->callback() will only be invoked:

  • for all() - as many times as there are occurrences matched in the subject.
  • for only(int) - the same as all(), but up to an int limit.
  • for first() - once if an occurrence is matched; or not at all if it's not.

Replace first

$subject = 'I like scandinavia: Sweden, Norway and Denmark';
pattern('[A-Z][a-z]+')->replace($subject)->first()->callback(function (Match $match) {
return strtoupper($match->text());
});
'I like scandinavia: SWEDEN, Norway and Denmark'

Of course, the callback is only invoked if your subject is matched with the pattern.

Replace multiple

all()

Replacing all matched occurrences is the most common use-case:

$subject = 'I like scandinavia: Sweden, Norway and Denmark';
pattern('[A-Z][a-z]+')->replace($subject)->all()->callback(function (Match $m) {
return strtoupper($m->text());
});
'I like scandinavia: SWEDEN, NORWAY and DENMARK'

only()

You can also limit the amount of replacements done with only().

$subject = 'I like scandinavia: Sweden, Norway and Denmark';
// In T-Regx, Match details can be cast to string, returning the whole match
pattern('[A-Z][a-z]+')->replace($subject)->only(2)->callback('strtoupper');
'I like scandinavia: SWEDEN, NORWAY and Denmark'

Return types

replace()->callback() only accepts string, Match or MatchGroup as its return type.

We believe that returning anything, that's not a string, match or a group can be a sign of a bug! Moreover, converting them silently would break our "Explicity rule".

pattern('\w+')->replace("Apples are cool")->first()->callback(function (Match $match) {
return 2; // <- throws InvalidReturnValueException
return true; // <- throws InvalidReturnValueException
return null; // <- throws InvalidReturnValueException
});

Only string, Match or MatchGroup are allowed.

pattern('([A-Z])\w+')->replace("Apples are cool")->first()->callback(function (Match $match) {
return 'orange'; // string
return $match; // match
return $match->group(1); // group
});

Explicit string

If you'd like to replace an occurrence with a numeric value (for example '12'), an empty string or 'true'/'false' literals - just return them as string explicitly.

pattern('\w+')->replace("Apples are cool")->first()->callback(function (Match $match) {
return strval(2); // ok
return true ? 'true' : 'false'; // ok
return null ? '' : $something; // ok
return $match->text(); // ok
return (string) $match; // ok
return $match->group('captured')->text(); // ok, if group exists and was matched
return $match; // ok
return $match->group('captured'); // ok, if group exists and was matched
});

Variable callbacks

You can call replace()->callback() for any valid PHP callable which accepts one string parameter (or no parameters) and returns string.

pattern('\w+')->replace('Apples are cool')->first()->callback('strtoupper');
'APPLES are cool'

In this example, Match will be cast to string, which is the same as calling Match.text() method.

Last updated on