-2

Basically what I'm looking for is the PHP version of this thread: Find, replace, and increment at each occurence of string

I would like to replace the keyword following > at the start of rach line with an incrementing counter.

If my input is:

>num, blah, blah, blah

ATCGACTGAATCGA

>num, blah, blah, blah

ATCGATCGATCGATCG

>num, blah, blah, blah

ATCGATCGATCGATCG

I would like it to be...

>0, blah, blah, blah

ATCGACTGAATCGA

>1, blah, blah, blah

ATCGATCGATCGATCG

>2, blah, blah, blah

ATCGATCGATCGATCG
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
Circle B
  • 1,616
  • 3
  • 26
  • 45

5 Answers5

2
$str = 'a hello a some a';
$i = 0;

while (strpos($str, 'a') !== false)
{
    $str = preg_replace('/a/', $i++, $str, 1);
}

echo $str;
Joe
  • 15,669
  • 4
  • 48
  • 83
  • I don't support the use of iterated `preg_replace()` calls, but if you are going to use a technique like this, then you can eliminate the extra iterated `strpos()` calls and use the count reference variable from `preg_replace()` in the condition of a do-while loop like this: https://stackoverflow.com/a/64964297/2943403 – mickmackusa Dec 19 '20 at 23:04
1
preg_replace(array_fill(0, 5, '/'.$findme.'/'), range(1, 5), $string, 1);

Example:

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

Output

a b 1 c 2 d 3 e f g 4 h 5
va5ja
  • 473
  • 1
  • 3
  • 8
  • This unexplained snippet suffers the same lack of directness as Joe's answer. Every time `preg_replace()` processes a new element in the first parameter, it checks the full string from the start every time. This means that characters that were checked in previous sweeps are checked again while searching for the first remaining match. – mickmackusa Dec 19 '20 at 22:52
1

I prefer to use preg_replace_callback() for this task . It is a more direct solution than making iterated single preg_replace() calls which restart from the beginning of the string each time (checking text that has already been replaced).

  • ^ means the start of a line because of the m pattern modifier.
  • \K means restart the full string match. This effectively prevents the literal > from being replaced and so only the literal string num is replaced.
  • the static counter declaration will only set $counter to 0 on the first visit.
  • the custom function does not need to receive the matched substring because the entire full string match is to be replaced.

Code: (Demo)

$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
     );
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
0

If I understood your question properly...

<?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);
Jordan Arsenault
  • 7,100
  • 8
  • 53
  • 96
  • While this solution may work on the provided sample, it is not suitable for general use cases because `str_replace()` has no way of limiting its number of replacements. This means that the function may incorrectly replace substrings later in the qualifying line. – mickmackusa Dec 19 '20 at 22:55
  • The same can be said about dividing the indexes by two to calculate the desired number in the replacement -- it is just not suitable for general use cases. – mickmackusa Dec 19 '20 at 23:02
-2

Here's my two cents

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

The above function is used to replace the string occurence only once, but you are free to edit the function to perform every other possible operation.

Anand Sainath
  • 1,807
  • 3
  • 22
  • 48
  • This answer does not directly, specifically provide the desired output for the question asked and can be safely discarded from the pool of correct answers. – mickmackusa Dec 19 '20 at 23:00