Philip G
Philip G

Reputation: 4104

Replace all quote marks but leave escaped characters

I'm trying to remove all quote characters from a string but not those that are escaped.

Example:

#TEST string "quoted part\" which escapes" other "quoted string"

Should result in:

#TEST string quoted part\" which escapes other quoted string

I tried to achieve this using

$string = '#TEST string "quoted part\" which escapes" other "quoted string"'
preg_replace("/(?>=\\)([\"])/","", $string);

But can't seem to find a match pattern.

Any help or tip on an other approach

Upvotes: 1

Views: 257

Answers (3)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626738

While (*SKIP)(*F) is a good technique all in all, it seems you may use a mere negative lookbehind in this case, where no other escape entities may appear but escaped quotes:

preg_replace("/(?<!\\\\)[\"']/","", $string);

See the regex demo.

Here, the regex matches...

  • (?<!\\\\) - a position inside the string that is not immediately preceded with a literal backslash (note that in PHP string literals, you need two backslashes to define a literal backslash, and to match a literal backslash with a regex pattern, the literal backslash in the string literal must be doubled since the backslash is a special regex metacharacter)
  • [\"'] - a double or single quote.

PHP demo:

$str = '#TEST string "quoted part\\" witch escape" other "quoted string"';
$res = preg_replace('/(?<!\\\\)[\'"]/', '', $str);
echo $res;
// => #TEST string quoted part\" witch escape other quoted string

In case backslashes may also be escaped in the input, you need to make sure you do not match a " that comes after two \\ (since in that case, a " is not escaped):

preg_replace("/(?<!\\\\)((?:\\\\{2})*)[\"']/",'$1', $string);

The ((?:\\\\{2})*) part will capture paired \s before " or ' and will put them back with the help of the $1 backreference.

Upvotes: 2

Oto Shavadze
Oto Shavadze

Reputation: 42753

May be this

$str = '#TEST string "quoted part\" witch escape" other "quoted string"';

echo preg_replace("#([^\\\])\"#", "$1", $str);

Upvotes: 1

Jan
Jan

Reputation: 43169

A very good example for (*SKIP)(*FAIL):

\\['"](*SKIP)(*FAIL)|["']

Replace this with an empty string and you're fine. See a demo on regex101.com.


In PHP this would be (you need to escape the backslash as well):

<?php

$string = <<<DATA
#TEST string "quoted part\" witch escape" other "quoted string"
DATA;

$regex = '~\\\\[\'"](*SKIP)(*FAIL)|["\']~';

$string = preg_replace($regex, '', $string);
echo $string;

?>

See a demo on ideone.com.

Upvotes: 2

Related Questions