-2
$string = "Apple
Foo
Banana
...
Banana
Foo
Other text
...
Apple";

I have text where single rows are duplicated after a row "...".

The rows before and after that can be anything ("Foo"), but also be a duplicate (without "..." like "Apple").

The "..."-row can appear multiple times without a duplicate row after it.

I only want to remove duplicated rows which have a "..." row inbetween.

In other words: Remove the line after "..." if it's the same as above "..."

How can I match

Banana
...
Banana

to remove the duplicated row:

Banana

so the result is

$string = "Apple
Foo
Banana
...
Foo
Other text
...
Apple";

Cheers!

Martin
  • 2,007
  • 6
  • 28
  • 44

4 Answers4

1
$lines = explode("\n", $string);  
$uniqueLines = array_unique(lines);
$result = implode("\n", $uniqueLines);
Sarfraz
  • 377,238
  • 77
  • 533
  • 578
CodeCaster
  • 147,647
  • 23
  • 218
  • 272
1

Here is how you can remove duplicate lines in the string:

$string = implode( "\n", array_unique( explode( "\n", $string)));

explode() the string into an array on the newline, call array_unique() on the resulting array, and join the string back together with implode().

Output:

Text row A
Foo
Text row B
...
Text row C

However, note that the output doesn't perfectly match your desired output, as your desired output conflicts with your definition of the problem.

Demo

nickb
  • 59,313
  • 13
  • 108
  • 143
  • Sorry my example was not clear enough. I only want to remove duplicated rows which have a "..." row inbetween. – Martin Jun 04 '12 at 14:18
0

I'm not sure I understand all the conditions (could you have duplicates before the ... for example), but how about $string = implode("\n", array_unique(explode("\n", $string)));

Update Brute force solution:

$string = "Apple\nFoo\nBanana\n...\nBanana\nFoo\nOther text\n...\nApple\n";
$string2 = "";

$arr = explode("\n", $string);

$string2 .= $arr[0] . "\n";
$string2 .= $arr[1] . "\n";

for ($i=2; $i<count($arr); $i++)
{
    if ($arr[$i-1] != '...' || $arr[$i-2] != $arr[$i])
    {
        $string2 .= $arr[$i] . "\n";
    }

}

echo $string2;
danneth
  • 2,721
  • 1
  • 23
  • 31
  • Updated with a brute force solution (though I'm sure there's a neat RegExp way to solve this) – danneth Jun 04 '12 at 15:18
  • Welcome! You should probably check that the `explode` returns two items before blindly appending them to the string. Otherwise you'll get some funky results if the input string is empty (or doesn't contain newlines). – danneth Jun 05 '12 at 06:58
0

If the task is to just remove the line following the line with three dots:

echo preg_replace("/^(.+?)\r?\n(\.{3})\r?\n\\1/m", "\\1\n\\2", $string);

The expression matches:

  • a whole line comprising at least one character (1)
  • three dots on a single line (2)
  • a whole line comprising at least one character (1)

The /m modifier is used to select multi-line mode, in which ^ and $ carry the meaning of start and end of the line.

The \\1 back reference is used to match whatever was before the three dots.

The replacement '\\1' is needed to place back the matched line with three dots.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309