Заменить подстроки увеличенным значением счетчика

В основном я ищу PHP-версию этого потока: Найти, заменить и увеличить при каждом появлении строки

Я хотел бы заменить ключевое слово, следующее за > в начале строки rach, на увеличивающийся счетчик.

Если мой ввод:

>num, blah, blah, blah

ATCGACTGAATCGA

>num, blah, blah, blah

ATCGATCGATCGATCG

>num, blah, blah, blah

ATCGATCGATCGATCG

Я хотел бы, чтобы это было...

>0, blah, blah, blah

ATCGACTGAATCGA

>1, blah, blah, blah

ATCGATCGATCGATCG

>2, blah, blah, blah

ATCGATCGATCGATCG

person Circle B    schedule 14.02.2012    source источник


Ответы (5)


preg_replace(array_fill(0, 5, '/'.$findme.'/'), range(1, 5), $string, 1);

Пример:

preg_replace(array_fill(0, 5, '/\?/'), range(1, 5), 'a b ? c ? d ? e f g ? h ?', 1);

Выход

a b 1 c 2 d 3 e f g 4 h 5
person va5ja    schedule 25.03.2014
comment
Этот необъяснимый фрагмент страдает таким же отсутствием прямоты, как и ответ Джо. Каждый раз, когда preg_replace() обрабатывает новый элемент в первом параметре, он каждый раз проверяет всю строку с самого начала. Это означает, что символы, которые были проверены в предыдущих проверках, проверяются снова при поиске первого оставшегося совпадения. - person mickmackusa; 20.12.2020

Если я правильно понял ваш вопрос...

<?php
//data resides in data.txt
$file = file('data.txt');
//new data will be pushed into here.
$new = array();
//fill up the array
foreach($file as $fK =>$fV) $new[] = (substr($fV, 0, 1)==">")? str_replace("num", $fK/2, $fV) : $fV;
//optionally print it out in the browser.
echo "<pre>";
print_r($new);
echo "</pre>";
//optionally write to file...
$output = fopen("output.txt", 'w');
foreach($new as $n) fwrite($output, $n);
fclose($output);
person Jordan Arseno    schedule 14.02.2012
comment
Хотя это решение может работать с предоставленным образцом, оно не подходит для общих случаев использования, поскольку str_replace() не имеет возможности ограничить количество замен. Это означает, что функция может неправильно заменить подстроки позже в уточняющей строке. - person mickmackusa; 20.12.2020
comment
То же самое можно сказать и о делении индексов на два для вычисления нужного числа в замене — это просто не подходит для общих случаев использования. - person mickmackusa; 20.12.2020

Я предпочитаю использовать preg_replace_callback() для этой задачи. Это более прямое решение, чем повторяющиеся одиночные вызовы preg_replace(), которые каждый раз перезапускаются с начала строки (проверка текста, который уже был заменен).

  • ^ означает начало строки из-за модификатора шаблона m.
  • \K означает перезапуск полного соответствия строки. Это эффективно предотвращает замену литерала >, поэтому заменяется только литеральная строка num.
  • объявление счетчика static установит $counter в 0 только при первом посещении.
  • пользовательской функции не требуется получать совпадающую подстроку, поскольку необходимо заменить все полное совпадение строки.

Код: (Демо)

$text = <<<TEXT
>num, blah, blah, blah

ATCGACTGAATCGA

>num, blah, blah, blah

ATCGATCGATCGATCG

>num, blah, blah, blah

ATCGATCGATCGATCG
TEXT;

echo preg_replace_callback(
         "~^>\Knum~m",
         function () {
             static $counter = 0;
             return ++$counter;
         },
         $text
     );
person mickmackusa    schedule 19.12.2020

Вот мои два цента

function str_replace_once($correct, $wrong, $haystack) {
    $wrong_string = '/' . $wrong . '/';
    return preg_replace($wrong_string, $correct, $haystack, 1);
}

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

person Anand Sainath    schedule 14.02.2012
comment
Этот ответ напрямую не дает желаемого результата для заданного вопроса и может быть безопасно исключен из пула правильных ответов. - person mickmackusa; 20.12.2020

person    schedule
comment
Я не поддерживаю использование повторяющихся вызовов preg_replace(), но если вы собираетесь использовать подобную технику, то вы можете исключить дополнительные повторные вызовы strpos() и использовать переменную ссылки count из preg_replace() в условиях цикла do-while. вот так: stackoverflow.com/a/64964297/2943403 - person mickmackusa; 20.12.2020