diff --git a/rules-tests/Php55/Rector/FuncCall/PregReplaceEModifierRector/Fixture/call_function_variable_hex_back_reference.php.inc b/rules-tests/Php55/Rector/FuncCall/PregReplaceEModifierRector/Fixture/call_function_variable_hex_back_reference.php.inc new file mode 100644 index 00000000000..ae1e255f260 --- /dev/null +++ b/rules-tests/Php55/Rector/FuncCall/PregReplaceEModifierRector/Fixture/call_function_variable_hex_back_reference.php.inc @@ -0,0 +1,29 @@ + +----- + diff --git a/src/PhpParser/Parser/InlineCodeParser.php b/src/PhpParser/Parser/InlineCodeParser.php index 6bc47e76d49..ca64905f5e5 100644 --- a/src/PhpParser/Parser/InlineCodeParser.php +++ b/src/PhpParser/Parser/InlineCodeParser.php @@ -52,6 +52,11 @@ */ private const string BACKREFERENCE_NO_DOUBLE_QUOTE_START_REGEX = '#(?\$\d+)#'; + /** + * @see https://regex101.com/r/13mVVg/1 + */ + private const string HEX_BACKREFERENCE_REGEX = '#0x(?\$\d+)#'; + public function __construct( private BetterStandardPrinter $betterStandardPrinter, private SimplePhpParser $simplePhpParser, @@ -81,6 +86,20 @@ public function parseString(string $fileContent): array public function stringify(Expr $expr): string { if ($expr instanceof String_) { + if (! str_contains($expr->value, "'") && ! str_contains($expr->value, '"') && StringUtils::isMatch( + $expr->value, + self::HEX_BACKREFERENCE_REGEX + )) { + return Strings::replace( + $expr->value, + self::HEX_BACKREFERENCE_REGEX, + static function (array $match): string { + $number = ltrim((string) $match['backreference'], '\\$'); + return 'hexdec($matches[' . $number . '])'; + } + ); + } + if (! StringUtils::isMatch($expr->value, self::BACKREFERENCE_NO_QUOTE_REGEX)) { return Strings::replace( $expr->value,