Syed
Syed

Reputation: 931

How to replace substrings from the substring between the two patterns in a string?

I have some strings e.g.

$str = '/some-folders/../pattern,replacement-area';

$str = '/some-folders/../pattern,also-replacement-area/parameter-one';

I want to replace all the occurrences of - to ~ if exists in the replacement area that is between /pattern, and optional /

The result must be

/some-folders/../pattern,replacement~area

/some-folders/../pattern,also~replacement~area/parameter-one

I just know about simple str_replace

$str = str_replace("-","~",$str);

Please provide efficient code as it will be run many times on a page.

Upvotes: 0

Views: 64

Answers (2)

anubhava
anubhava

Reputation: 785186

You can search using this regex:

(?:/pattern,|(?!^)\G)[^\n/-]*\K-

and replace using ~

RegEx Demo

RegEx Details:

  • (?:: Start non-capture group
    • /pattern,: Match /pattern,
    • |: OR
    • (?!^)\G: Start from end of previous match
  • ): End non-capture group
  • [^\n/-]*: Match 0 or more of any character that is not / and - and not a line break
  • \K: reset all the match info
  • -: Match a -

php code:

$str = '/some-folders/../pattern,also-replacement-area/parameter-one';
$repl = preg_replace('~(?:/pattern,|(?!^)\G)[^\n/-]*\K-~', '~', $str);
echo $repl . "\n";

Output:

/some-folders/../pattern,also~replacement~area/parameter-one

Upvotes: 2

Casimir et Hippolyte
Casimir et Hippolyte

Reputation: 89557

Always with the "glue" feature (this time expressed with the A modifier instead of the \G escape sequence), but with a different pattern structure that avoids the alternation:

echo preg_replace('~(?:^.*?/pattern,)?(?!^)[^/-]*+\K-~A', '~', $str);

regex demo
php demo

Notice: instead of the possessive quantifier here [^/-]*+, you can also use the (*COMMIT) backtracking control verb that is interesting to quickly abort the research when there's no dash in the string:

~(?:^.*?/pattern,)?(?!^)[^/-]*\K(*COMMIT)-~A

Upvotes: 2

Related Questions