3

I have:

$txt = ':D :D ":D" :D:D:D:D';

I want to preg_replace all :D to ^ and if ":D" then not replace.

===> output: '^ ^ ":D" ^^^^';
zx81
  • 41,100
  • 9
  • 89
  • 105
dqnhust
  • 33
  • 4

2 Answers2

4

(*SKIP)(*F) Magic

$replaced = preg_replace('~"[^"]+"(*SKIP)(*F)|:D~', '^', $yourstring);

In the demo, see the substitutions in the bottom pane.

This problem is a classic case of the technique explained in this question to "regex-match a pattern, excluding..."

The left side of the alternation | matches complete "quotes" then deliberately fails, after which the engine skips to the next position in the string. So the quotes are neutralized. The right side matches :D, and we know they are the right ones because they were not matched by the expression on the left.

Reference

Community
  • 1
  • 1
zx81
  • 41,100
  • 9
  • 89
  • 105
0

You could use a negative lookahead and lookbehind,

(?<!\"):D(?!\")

It matches :D which is not preceded by "(double quotes) and followed by ". Then the matched characters are replaced by ^

<?php
$string = ':D :D ":D" :D:D:D:D';
$pattern = "~(?<!\"):D(?!\")~";
$replacement = "^";
echo preg_replace($pattern, $replacement, $string);
?> //=> ^ ^ ":D" ^^^^

DEMO

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274