Регулярное выражение PHP: выбрать все, кроме последнего вхождения

#php #regex #preg-replace

#php #регулярное выражение #preg-заменить

Вопрос:

Я пытаюсь заменить все n без этого последнего nt на, чтобы сделать хороший отступ для рекурсивной функции.

 This
that
then
thar
these
them
  

должно стать:

 This
    that
    then
    thar
    these
them
  

Это то, что у меня есть: preg_replace('/n(. ?)n/','nt$1n',$var);

В настоящее время он выдает это:

 This
    that
then
thar
these
them
  

Краткий обзор:

Необходимо сделать отступ в каждой строке меньше первой и последней строки с помощью регулярного выражения, как я могу это сделать?

Комментарии:

1. пробовал это: неизвестный модификатор ‘g’, вот почему я в замешательстве.

2. Невозможно, чтобы этот код выдавал этот результат …. и это не так .

3. @Tomalakgeret’kal Ваш пример явно терпит неудачу.

4. @Korvin: Что? Это пример OP. Конечно, это не удается, иначе его бы здесь не было. Я просто демонстрирую, что он выходит из строя по-другому, чем утверждал OP.

5. О, хорошо, я неправильно истолковал.

Ответ №1:

Вы можете использовать предварительный просмотр:

 $var = preg_replace('/n(?=.*?n)/', "nt", $var);
  

Посмотрите, как это работает здесь: ideone

Ответ №2:

После исправления проблемы с кавычками ваш вывод на самом деле выглядит так:

 This
    that
then
    thar
these
them
  

Используйте позитивный прогноз, чтобы не допустить, чтобы это конечное n значение было съедено регулярным выражением поиска. Ваш «курсор» уже был установлен за его пределами, поэтому переписывалась только каждая вторая строка; ваши совпадающие «зоны» перекрывались.

 echo preg_replace('/n(. ?)(?=n)/', "nt$1", $input);
//          newline-^  ^-text ^-lookahead ^- replacement
  

Живая демонстрация.

Ответ №3:

 preg_replace('/n(. ?)(?=n)/',"nt$1",$var);
  

Изменил второе n , чтобы оно было исходным (?=n) , иначе вы столкнулись бы с проблемами, когда регулярное выражение не распознает совпадающие совпадения.

http://ideone.com/1JHGY

Ответ №4:

Пусть начнется downwoting, но зачем использовать regex для этого?

 <?php
$e = explode("n",$oldstr);
$str = $e[count($e) - 1]; 
unset($e[count($e) - 1]);
$str = implode("nt",$e)."n".$str;
echo $str;
?>
  

На самом деле, str_replace имеет параметр «count», но я просто не могу заставить его работать с php 5.3.0 (найдено сообщение об ошибке). Это должно сработать:

 <?php
$count = substr_count($oldstr,"n") - 1;
$newstr = str_replace("n","nt",$oldstr,amp;$count);
?>
  

Комментарии:

1. Зачем проходить через все это, когда регулярное выражение позволит вам сделать это в одной строке кода?

2. @AlanMoore Не говоря уже о том, что регулярное выражение можно легко применить к другому языку.