5

I need to replace last occurrence of at least double new line (\n\n) in a string, so it should be \n\n or \n\n\n or \n\n\n\n an so on (at least 2 \n) by the "@@". I think that it should be preg_replace. I have tried many option that is in the answers here on stackoverflow, but all this options have some cases that was not catched. I tried regex101 site to prepare regular expression, but I am not strong in this, so I found some solution that looks like working on the site (/((\\n){2,})+(?!.*((\\n){2,})+)/i), but when I am trying it in my code, i doesn't work.

Another one was ([\\n\\n])+(.[^\\n\\n])*$, but this one catched also last nn

The test string was:

Storage\nThe powerful quad-core Intel X5 processor in Transformer Book T101HA means you'll have no problem breezing through all your everyday tasks,\nwith seamless multitasking allowing you to get more done in less time. Storage is conveniently flexible, too. Inside, there's 128GB of super-fast flash storage, and it's easily expandable via the micro SD card slot. You also get you a year's free unlimited cloud storage on ASUS WebStorage!\n\nColor|White/Gold\n\n\n\n\n\nCPU|Innn dsafdsfdfa \n\n\n\n\n\n\n\n dfnn

So the result should be:

Storage\nThe powerful quad-core Intel X5 processor in Transformer Book T101HA means you'll have no problem breezing through all your everyday tasks,\nwith seamless multitasking allowing you to get more done in less time. Storage is conveniently flexible, too. Inside, there's 128GB of super-fast flash storage, and it's easily expandable via the micro SD card slot. You also get you a year's free unlimited cloud storage on ASUS WebStorage!\n\nColor|White/Gold\n\n\n\n\n\nCPU|Innn dsafdsfdfa @@ dfnn

Can anyone help with this and maybe in addition explain the logic of the answered regex.

Thanks a lot.

IncreMan
  • 356
  • 3
  • 10
  • Note that you could do this by use of [greed](http://www.regular-expressions.info/repeat.html#greedy) without any lookahead. Search for [`/^.*\V\K\R{2,}/s`](https://www.regex101.com/r/zOmdJ5/1) and replace with `@@`. The `.*` will eat up until the last `\V` *non-vertical space* that's followed by two or more newlines `\R`. [`\K` resets](http://www.rexegg.com/regex-php.html#K) beginning of the reported match (sets from where to start replacing). See [this demo at eval.in](https://eval.in/704280). – bobble bubble Dec 25 '16 at 14:10

1 Answers1

5

You may use

/\n{2,}(?!.*\n{2})/s

See the regex demo

Details:

  • \n{2,} - 2 or more newlines
  • (?!.*\n{2}) - not followed with any 0+ chars followed with 2 newlines.

If any linebreak is meant, replace \n with \R.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • Thank you very much, i have made some change as i found that my string comes with **\r** before each **\n** so the final solution in my case is `/(\r\n){2,}(?!.*(\r\n){2})/s` – IncreMan Dec 25 '16 at 09:51
  • Actually, that is where `\R` is handy - `/\R{2,}(?!.*\R{2})/s`, `\R` matches any line breaks, CRLF, CR and LF. – Wiktor Stribiżew Dec 25 '16 at 11:02