2012-05-22 5 views
2

Я хочу заменить одно случайное слово, которое несколько в строке.PHP заменить случайное слово строки

Так скажем, строка

$str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty'; 

И давайте скажем, я хочу, чтобы заменить слово синий с красным, но только 2 раза в случайных позициях.

Таким образом, после функции делается вывод может быть как

I like red, blue is my favorite colour because red is very nice and blue is pretty 

Еще один может быть

I like blue, red is my favorite colour because blue is very nice and red is pretty 

Так что я хочу, чтобы заменить то же слово несколько раз, но каждый раз, когда на разных позициях.

Я думал об использовании preg_match, но у этого нет опции, чтобы положение слов peing было случайным.

Есть ли у кого-нибудь ключ к достижению этого?

ответ

3

Многое, как я ненавидела использовать регулярное выражение для чего-то, который находится на лице его очень просто, для того, чтобы гарантии точности п заменяет Я думаю, что это может помочь в этом, так как он позволяет использовать легко использовать array_rand() , который делает именно то, что вы хотите - выберите n случайные предметы из списка неопределенной длины (УЛУЧШЕНО).

<?php 

    function replace_n_occurences ($str, $search, $replace, $n) { 

     // Get all occurences of $search and their offsets within the string 
     $count = preg_match_all('/\b'.preg_quote($search, '/').'\b/', $str, $matches, PREG_OFFSET_CAPTURE); 

     // Get string length information so we can account for replacement strings that are of a different length to the search string 
     $searchLen = strlen($search); 
     $diff = strlen($replace) - $searchLen; 
     $offset = 0; 

     // Loop $n random matches and replace them, if $n < 1 || $n > $count, replace all matches 
     $toReplace = ($n < 1 || $n > $count) ? array_keys($matches[0]) : (array) array_rand($matches[0], $n); 
     foreach ($toReplace as $match) { 
      $str = substr($str, 0, $matches[0][$match][1] + $offset).$replace.substr($str, $matches[0][$match][1] + $searchLen + $offset); 
      $offset += $diff; 
     } 

     return $str; 

    } 

    $str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty'; 

    $search = 'blue'; 
    $replace = 'red'; 
    $replaceCount = 2; 

    echo replace_n_occurences($str, $search, $replace, $replaceCount); 

See it working

1

Ну, вы могли бы использовать этот алгоритм:

  1. вычислить случайное количество раз вы хотите заменить строку
  2. взрываются строку в массив
  3. для этого массива заменить строку встречаемости только если случайное значение в диапазоне от 1 до 100% составляет 3 (, для примера)
  4. Уменьшение числа вычисленного в точке 1.
  5. Повторите, пока число не достигнет 0.
2
echo preg_replace_callback('/blue/', function($match) { return rand(0,100) > 50 ? $match[0] : 'red'; }, $str); 
+2

would't это не заменить 2 случайных вхождений «синий», а дает 50% шанс заменить каждое вхождение синего? – ben

+0

Да, но вы можете использовать счетчик, чтобы остановить замену через 2 раза. – Eugene

0
<?php 
$amount_to_replace = 2; 
$word_to_replace = 'blue'; 
$new_word = 'red'; 

$str = 'I like blue, blue is my favorite colour because blue is very nice and blue is pretty'; 

$words = explode(' ', $str); //convert string to array of words 
$blue_keys = array_keys($words, $word_to_replace); //get index of all $word_to_replace 

if(count($blue_keys) <= $amount_to_replace) { //if there are less to replace, we don't need to randomly choose. just replace them all 
    $keys_to_replace = array_keys($blue_keys); 
} 
else { 
    $keys_to_replace = array(); 
    while(count($keys_to_replace) < $amount_to_replace) { //while we have more to choose 
     $replacement_key = rand(0, count($blue_keys) -1); 
     if(in_array($replacement_key, $keys_to_replace)) continue; //we have already chosen to replace this word, don't add it again 
     else { 
      $keys_to_replace[] = $replacement_key; 
     } 
    } 
} 

foreach($keys_to_replace as $replacement_key) { 
    $words[$blue_keys[$replacement_key]] = $new_word; 
} 

$new_str = implode(' ', $words); //convert array of words back into string 
echo $new_str."\n"; 
?> 

нотабене Я просто понял, что это не заменит первый синий цвет, так как он вводится в массив слов как «синий» и поэтому не совпадает с вызовом array_keys.

+0

было бы здорово, если бы это могло обрабатывать $ n замены –

Смежные вопросы