If you need to do exact escape sequences like PHP does, you need a long version, which is the DoubleQuoted class. I expanded the input line a bit to cover more escape sequences than in your question to make this more general:
$content = '\\\\t\tThis variable\\string is\x20not\40set by me.\nCannot \do anything about it.\n'; $dq = new DoubleQuoted($content); echo $dq;
Output:
\\t This variable\string is not set by me. Cannot \do anything about it.
However, if you approach this well, there is a PHP function called stripcslashes , for comparison, I've added the result of this and the double quote string of PHP:
echo stripcslashes($content), "\n"; $compare = "\\\\t\tThis variable\\string is\x20not\40set by me.\nCannot \do anything about it.\n"; echo $compare, "\n";
Output:
\t This variablestring is not set by me. Cannot do anything about it. \\t This variable\string is not set by me. Cannot \do anything about it.
As you can see, stripcslashes discards some characters here compared to the original PHP output.
( Edit: See also my other answer , which offers something simple and enjoyable with cstripslashes and preg_replace .)
If stripcslashes does not fit, DoubleQuoted exists. The constructor accepts a string that is treated as a double-quoted string (minus the replacement of variables, only escape sequences of the character).
As manual outlines, there are several control sequences. They look like regular expressions and everything starts with \ , so it is almost suitable for using regular expressions to replace them.
However, there is one exception: \\ skip the escape sequence. The regular expression must have feedback and / or atomic groups to handle this, and I donβt own them, so I just did a simple trick: I applied regular expressions only to those parts of the line that do not contain \\ , just breaking the line first and then unleashing it again.
Two regular expression-based functions replace the functions, preg_replace Doc and preg_replace_callback Doc , and allow you to work with arrays, so this is pretty easy to do.
This is done in the __toString() Doc :
class DoubleQuoted { ... private $string; public function __construct($string) { $this->string = $string; } ... public function __toString() { $this->exception = NULL; $patterns = $this->getPatterns(); $callback = $this->getCallback(); $parts = explode('\\\\', $this->string); try { $parts = preg_replace_callback($patterns, $callback, $parts); } catch(Exception $e) { $this->exception = $e; return FALSE;
See explode Doc and implode Doc . They take care that preg_replace_callback does not work on any line containing \\ . Thus, the replacement operation was relieved of the burden to address these special cases. This is a callback function that is called by preg_replace_callback for each pattern match. I wrapped it in a close so that it was not publicly available:
private function getCallback() { $map = $this->map; return function($matches) use ($map) { list($full, $type, $number) = $matches += array('', NULL, NULL); if (NULL === $type) throw new UnexpectedValueException(sprintf('Match was %s', $full)) ; if (NULL === $number) return isset($map[$type]) ? $map[$type] : '\\'.$type ; switch($type) { case 'x': return chr(hexdec($number)); case '': return chr(octdec($number)); default: throw new UnexpectedValueException(sprintf('Match was %s', $full)); } }; }
You need more information to figure this out, as this is no longer a complete class. I look at the missing points and add the missing code:
All templates of the βseekβ class contain subgroups of at least one. This is included in $type and is either the only character to be translated or an empty string for octal, and x for hexadecimal numbers.
The optional second group $number either not set ( NULL ) or contains an octal / hexadecimal number. The input $matches normalized to the just named variables on this line:
list($full, $type, $number) = $matches += array('', NULL, NULL);
Patterns are predefined as sequences in a private member variable:
private $sequences = array( '(n|r|t|v|f|\\$|")',
The getPatterns() function simply transfers these definitions to valid PCRE regular expressions, for example:
/\\(n|r|t|v|f|\$|")/ # single escape characters /\\()([0-7]{1,3})/ # octal /\\(x)([0-9A-Fa-f]{1,2})/ # hex
It is pretty simple:
private function getPatterns() { foreach($this->sequences as $sequence) $patterns[] = sprintf('/\\\\%s/', $sequence) ; return $patterns; }
Now that the patterns are laid out, this explains what $matches contains when the callback function is called.
Another thing you need to know to understand how the callback works is $map . This is just an array containing single replacement characters:
private $map = array( 'n' => "\n", 'r' => "\r", 't' => "\t", 'v' => "\v", 'f' => "\f", '$' => '$', '"' => '"', );
And that is pretty much for the class. There is another private variable $this->exception , which is used for storage if an exception was thrown as __toString() cannot throw exceptions and will result in a fatal error if this happens in the callback function. Thus, it gets and is stored in the private variable of the class, and here is this part of the code:
... public function __toString() { $this->exception = NULL; ... try { $parts = preg_replace_callback($patterns, $callback, $parts); } catch(Exception $e) { $this->exception = $e; return FALSE;
In case of an exception when replacing, the function exists with FALSE , which will lead to a catchable exception. The getter function makes an internal exception available:
private $exception; ... public function getException() { return $this->exception; }
To easily access the source string, you can add another recipient to get this:
public function getString() { return $this->string; }
And that whole class. Hope this will be helpful.