preg_replace() replace second occurrence

后端 未结 3 1364
没有蜡笔的小新
没有蜡笔的小新 2020-12-19 19:57

This is what I do now:

if (strpos($routeName,\'/nl/\') !== false) {
    $routeName = preg_replace(\'/nl/\', $lang , $routeName, 1 );
}

I re

相关标签:
3条回答
  • 2020-12-19 20:11

    The answer by @Casimir seems rather applicable to most cases. Another alternative is preg_replace_callback with a counter. In case you need a specific n-th occurence to be replaced only.

    #-- regex-replace an occurence by count
    $s = "…abc…abc…abc…";
    $counter = 1;
    $s = preg_replace_callback("/abc/", function ($m) use (&$counter) {
    
         #-- replacement for 2nd occurence of "abc"
         if ($counter++ == 2) {
              return "def";
         }
    
         #-- else leave current match
         return $m[0];
    
    }, $s);
    

    This utilizes a local $counter, incremented within the callback on each occurence, and there simply checked for a fixed position here.

    0 讨论(0)
  • 2020-12-19 20:12

    So firstly you check if there is any occurrence and if so, you replace it. You could count the occurrences (unsing substr_count) instead to know how many of them exist. Then, just replace them bit by bit if that's what you need.

    $occurrences = substr_count($routeName, '/nl/');
    if ($occurrences > 0) {
      $routeName = preg_replace('/nl/', $lang , $routeName, 1 );
      if ($occurrences > 1) {  
        // second replace
        $routeName = preg_replace('/nl/', $lang , $routeName, 1 );
      }
    }
    

    If you only want to replace the second occurrence (as stated by you later on in the comments), check out substr and read up on string functions in PHP. You can use the first occurrence, found using strpos as a start for substr and just use that for your replacement.

    <?php
    
    $routeName = 'http://example.nl/language/nl/peter-list/foo/bar?example=y23&source=nl';
    $lang = 'de';
    
    $routeNamePart1 = substr( $routeName, 0 , strpos($routeName,'nl') +4 );
    $routeNamePart2 = substr( $routeName, strpos($routeName,'nl') + 4);
    $routeNamePart2 = preg_replace('/nl/', $lang , $routeNamePart2, 1 );
    $routeName = $routeNamePart1 . $routeNamePart2;
    
    echo $routeName;
    

    See this working here.

    0 讨论(0)
  • 2020-12-19 20:24

    You can do that:

    $lang = 'de'
    $routeName = preg_replace('~/nl/.*?(?<=/)\Knl/~', "$lang/", $routeName, 1 );
    

    \K will remove all on the left from match result.(Thus, all that has been matched on the left with by /nl/.*?(?<=/) will not be replaced.)

    I use a lookbehind (?<=/) instead of a literal / to deal with this specific case /nl/nl/ (In this case .*? matches an empty substring.)

    0 讨论(0)
提交回复
热议问题