preg_replace: Compilation failed: missing terminating ]

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
blither
Forum Newbie
Posts: 7
Joined: Mon Oct 25, 2010 9:47 pm

preg_replace: Compilation failed: missing terminating ]

Post by blither »

Am I building my regular expression in correctly?

Code: Select all

$var='some_text\_with_escapes';
echo $var;
echo "\n---\n";
echo preg_replace('/[^\]_/',' ',$var);
I have also tried it with /[^\\]_/ and I still get the same error.

Any thoughts?

Thanks.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: preg_replace: Compilation failed: missing terminating ]

Post by McInfo »

Backslash is a special character in both regex and PHP strings. The literal backslash needs to be escaped in the regex...

Code: Select all

/[^\\]_/
...but because the regex is in a string, both of those backslashes need to be escaped.

Code: Select all

'/[^\\\\]_/'
Depending on what you are trying to replace, you might want to use this pattern instead. It uses a negative look-behind assertion so underscores that are not preceded by a backslash will be matched.

Code: Select all

'/(?<!\\\\)_/'
blither
Forum Newbie
Posts: 7
Joined: Mon Oct 25, 2010 9:47 pm

Re: preg_replace: Compilation failed: missing terminating ]

Post by blither »

Cool thanks.

I thought that a single quote meant it didn't need to be escaped for php? And I also thought that for regular expressions characters in brackets didn't get escaped?
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: preg_replace: Compilation failed: missing terminating ]

Post by McInfo »

The two characters that can be escaped by a backslash in a single-quoted string are the single quote and the backslash itself. The quote must be escapable so it can appear in the string without terminating the string (1), and the backslash must be escapable so it can appear as the last character in the string without escaping the single quote that terminates the string (2).

Code: Select all

'\'' /*(1)*/
'\\' /*(2)*/
It is necessary to escape the backslash in the regular expression so that the right square bracket that terminates the character class will not be escaped. Therefore, two backslashes must appear together to satisfy the regular expression and both become literals in the string.

Code: Select all

/[^\\]/
It is true that a backslash can appear in a single-quoted string without being escaped, but if two backslashes appear in the string, they will be folded into a single backslash. Therefore, four backslashes (two pairs) must appear in the string.

Code: Select all

'/[^\\\\]/'
blither
Forum Newbie
Posts: 7
Joined: Mon Oct 25, 2010 9:47 pm

Re: preg_replace: Compilation failed: missing terminating ]

Post by blither »

Thanks for the explanation I could have sworn regular expressions didn't need to be escaped for square brackets. But anyway thanks for the answer.
User avatar
McInfo
DevNet Resident
Posts: 1532
Joined: Wed Apr 01, 2009 1:31 pm

Re: preg_replace: Compilation failed: missing terminating ]

Post by McInfo »

Consider this. It matches characters that are not right square brackets.

Code: Select all

/[^\]]/
Without escaping, there is be ambiguity. Where does the character class terminate?

Code: Select all

/[^]]/
Post Reply