Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interpret escape characters in single quoted string

Having a single-quoted string:

$content = '\tThis variable is not set by me.\nCannot do anything about it.\n';

I would like to inerpret/process the string as if it was double-quoted. In other words I would like to replace all the possible escape characters (not just tab and linefeed as in this example) with the real values, taking into account that backslash might be escaped as well, thus '\\n' needs to be replaced by '\n'. eval() would easily do what I need but I cannot use it.

Is there some simple solution?

(A similar thread that I found deals with expansion of variables in the single-quoted string while I'm after replacing escape characters.)

like image 437
tmt Avatar asked Nov 29 '11 11:11

tmt


People also ask

What is the escape character for single quote?

No escaping is used with single quotes. Use a double backslash as the escape character for backslash.

Can you use single quotes in single quotes escape characters?

A double-quoted string can have single quotes without escaping them, conversely, a single-quoted string can have double quotes within it without having to escape them. Double quotes ( \" ) must escape a double quote and vice versa single quotes ( \' ) must escape a single quote.

How do you handle a single quote in a string?

A single quote is not used where there is already a quoted string. So you can overcome this issue by using a backslash following the single quote. Here the backslash and a quote are used in the “don't” word. The whole string is accompanied by the '$' sign at the start of the declaration of the variable.

What are escape characters in a string?

In the platform, the backslash character ( \ ) is used to escape values within strings. The character following the escaping character is treated as a string literal.


1 Answers

There is a very simple way to do this, based on preg_replaceDoc and stripcslashes, both build in:

preg_replace_callback(
    '/\\\\([nrtvf\\\\$"]|[0-7]{1,3}|\x[0-9A-Fa-f]{1,2})/',
    fn($matches) => stripcslashes($matches[0]), $content
);

This works as long as "\\n" should become "\n" and the like. Demo

If you're looking for processing these strings literally, see my previous answer.

Edit: You asked in a comment:

I'm just a bit puzzled what's the difference between the output of this and stripcslashes() directly [?]

The difference is not always visible, but there is one: stripcslashes will remove the \ chracter if no escape sequence follows. In PHP strings, the slash is not be dropped in that case. An example, "\d", d is not a special character, so PHP preserves the slash:

$content = '\d';
$content; # \d
stripcslashes($content); # d
preg_replace(..., $content); # \d

That's why preg_replace is useful here, it will only apply the function on those substrings where stripcslashes works as intended: all valid escape sequences.


After a couple of years the answer is updated for PHP 7.4+.

The original answer did contain a Demo with using the e (eval) modifier in the regex. For (mostly good) reasons it has been removed from PHP and refuses to work spilling an error like:

PHP Warning: preg_replace(): The /e modifier is no longer supported, use preg_replace_callback

In case the new version gives syntax errors (e.g. PHP < 7.4) or because of preferrence, replace the arrow function with an anonymous one like:

static function (array $matches): string {
    return stripcslashes($matches[0]);
}

Please see Replace preg_replace() e modifier with preg_replace_callback for more on-site Q&A resources on the topic to replace the e modifier in general, it was deprecated in PHP 5.5.0:

[The] e (PREG_REPLACE_EVAL) [...] was DEPRECATED in PHP 5.5.0 (Jun 2013), and REMOVED as of PHP 7.0.0 (Dec 2015).

from the PHP manual

like image 180
hakre Avatar answered Oct 08 '22 19:10

hakre