From e6da11c297e566f9eca380439d989b9fe9ec794c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Baptiste=20Clavi=C3=A9?= Date: Thu, 10 Mar 2016 12:33:16 +0100 Subject: [PATCH] [Yaml] Allow using _ in some numeric notations --- src/Symfony/Component/Yaml/Inline.php | 13 ++++++++++--- src/Symfony/Component/Yaml/Tests/InlineTest.php | 10 ++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index cc994b9562..43da4fd328 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -206,6 +206,7 @@ class Inline case Escaper::requiresDoubleQuoting($value): return Escaper::escapeWithDoubleQuotes($value); case Escaper::requiresSingleQuoting($value): + case preg_match('{^[0-9]+[_0-9]*$}', $value): case preg_match(self::getHexRegex(), $value): case preg_match(self::getTimestampRegex(), $value): return Escaper::escapeWithSingleQuotes($value); @@ -564,6 +565,9 @@ class Inline return; case 0 === strpos($scalar, '!!float '): return (float) substr($scalar, 8); + case preg_match('{^[+-]?[0-9][0-9_]*$}', $scalar): + $scalar = str_replace('_', '', (string) $scalar); + // omitting the break / return as integers are handled in the next case case ctype_digit($scalar): $raw = $scalar; $cast = (int) $scalar; @@ -576,6 +580,8 @@ class Inline return '0' == $scalar[1] ? octdec($scalar) : (((string) $raw === (string) $cast) ? $cast : $raw); case is_numeric($scalar): case preg_match(self::getHexRegex(), $scalar): + $scalar = str_replace('_', '', $scalar); + return '0x' === $scalar[0].$scalar[1] ? hexdec($scalar) : (float) $scalar; case '.inf' === $scalarLower: case '.nan' === $scalarLower: @@ -584,8 +590,9 @@ class Inline return log(0); case 0 === strpos($scalar, '!!binary '): return self::evaluateBinaryScalar(substr($scalar, 9)); - case preg_match('/^(-|\+)?[0-9,]+(\.[0-9]+)?$/', $scalar): - return (float) str_replace(',', '', $scalar); + case preg_match('/^(-|\+)?[0-9][0-9,]*(\.[0-9_]+)?$/', $scalar): + case preg_match('/^(-|\+)?[0-9][0-9_]*(\.[0-9_]+)?$/', $scalar): + return (float) str_replace(array(',', '_'), '', $scalar); case preg_match(self::getTimestampRegex(), $scalar): if (Yaml::PARSE_DATETIME & $flags) { return new \DateTime($scalar, new \DateTimeZone('UTC')); @@ -662,6 +669,6 @@ EOF; */ private static function getHexRegex() { - return '~^0x[0-9a-f]++$~i'; + return '~^0x[0-9a-f_]++$~i'; } } diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index aadb7ff6cb..7f77b68c52 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -286,11 +286,16 @@ class InlineTest extends \PHPUnit_Framework_TestCase array('true', true), array('12', 12), array('-12', -12), + array('1_2', 12), + array('_12', '_12'), + array('12_', 12), array('"quoted string"', 'quoted string'), array("'quoted string'", 'quoted string'), array('12.30e+02', 12.30e+02), array('0x4D2', 0x4D2), + array('0x_4_D_2_', 0x4D2), array('02333', 02333), + array('0_2_3_3_3', 02333), array('.Inf', -log(0)), array('-.Inf', log(0)), array("'686e444'", '686e444'), @@ -438,10 +443,15 @@ class InlineTest extends \PHPUnit_Framework_TestCase array('false', false), array('true', true), array('12', 12), + array("'1_2'", '1_2'), + array('_12', '_12'), + array("'12_'", '12_'), array("'quoted string'", 'quoted string'), array('!!float 1230', 12.30e+02), array('1234', 0x4D2), array('1243', 02333), + array("'0x_4_D_2_'", '0x_4_D_2_'), + array("'0_2_3_3_3'", '0_2_3_3_3'), array('.Inf', -log(0)), array('-.Inf', log(0)), array("'686e444'", '686e444'),