dqsvnsad79721 2018-11-25 13:08
浏览 232
已采纳

PHP:preg_replace只是数组中第一个匹配的字符串

I've started with preg_replace in PHP and I wonder how I can replace only first matching array key with a specified array value cause I set preg_replace number of changes parameter to '1' and it's changing more than one time anyways. I also splitted my string to single words and I'm examining them one by one:

<?php
  $internal_message = 'Hey, this is awesome!';

  $words = array(
     '/wesome(\W|$)/' => 'wful',
     '/wful(\W|$)/' => 'wesome',
     '/^this(\W|$)/' => 'that',
     '/^that(\W|$)/' => 'this'
  );

  $splitted_message = preg_split("/[\s]+/", $internal_message);
  $words_num = count($splitted_message);

  for($i=0; $i<$words_num; $i++) {
     $splitted_message[$i] = preg_replace(array_keys($words), array_values($words), $splitted_message[$i], 1);
  }

  $message = implode(" ", $splitted_message);
  echo $message;
?>

I want this to be on output:

Hey, that is awful

(one suffix change, one word change and stops)

Not this:

Hey, this is awesome

(two suffix changes, two word changes and back to original word & suffix...)

Maybe I can simplify this code? I also can't change order of the array keys and values cause there will be more suffixes and single words to change soon. I'm kinda newbie in php coding and I'll be thankful for any help ;>

  • 写回答

1条回答 默认 最新

  • duanmei4362 2018-11-25 14:33
    关注

    You may use plain text in the associative array keys that you will use to create dynamic regex patterns from, and use preg_replace_callback to replace the found values with the replacements in one go.

    $internal_message = 'Hey, this is awesome!';
    
    $words = array(
        'wesome' => 'wful',
        'wful' => 'wesome',
        'this' => 'that',
        'that' => 'this'
    );
    $rx = '~(?:' . implode("|", array_keys($words)) . ')\b~';
    echo "$rx
    ";
    $message = preg_replace_callback($rx, function($m) use ($words) {
        return isset($words[$m[0]]) ? $words[$m[0]] : $m[0];
    }, $internal_message);
    echo $message;
    // => Hey, that is awful!
    

    See the PHP demo.

    The regex is

    ~(?:wesome|wful|this|that)\b~
    

    The (?:wesome|wful|this|that) is a non-capturing group that matches any of the values inside, and \b is a word boundary, a non-consuming pattern that ensures there is no letter, digit or _ after the suffix.

    The preg_replace_callback parses the string once, and when a match occurs, it is passed to the anonymous function (function($m)) together with the $words array (use ($words)) and if the $words array contains the found key (isset($words[$m[0]])) the corresponding value is returned ($words[$m[0]]) or the found match is returned otherwise ($m[0]).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?