/** * Parses number in lenient mode. * * Lenient parsing ignores everything that can be ignored, and tries to * extract number from the string, even if it's not well formed. * * Implementation is simple but should work more often than strict parsing. * * Algorithm: * 1. Find first digit * 2. Find last digit * 3. Find decimal separator between first and last digit (if any) * 4. Remove non-digits from integer part * 5. Remove non-digits from decimal part (optional) * 6. Try to match negative prefix before first digit * 7. Try to match negative suffix after last digit * * @param string $numberToParse Number to be parsed * @param array $parsedFormat Parsed format (from NumbersReader) * @param array $localizedSymbols An array with symbols to use * @return mixed Parsed float number or FALSE on failure */ protected function doParsingInLenientMode($numberToParse, array $parsedFormat, array $localizedSymbols) { $numberIsNegative = FALSE; $positionOfFirstDigit = NULL; $positionOfLastDigit = NULL; $charactersOfNumberString = str_split($numberToParse); foreach ($charactersOfNumberString as $position => $character) { if (ord($character) >= 48 && ord($character) <= 57) { $positionOfFirstDigit = $position; break; } } if ($positionOfFirstDigit === NULL) { return FALSE; } krsort($charactersOfNumberString); foreach ($charactersOfNumberString as $position => $character) { if (ord($character) >= 48 && ord($character) <= 57) { $positionOfLastDigit = $position; break; } } $positionOfDecimalSeparator = strrpos($numberToParse, $localizedSymbols['decimal'], $positionOfFirstDigit); if ($positionOfDecimalSeparator === FALSE) { $integerPart = substr($numberToParse, $positionOfFirstDigit, $positionOfLastDigit - $positionOfFirstDigit + 1); $decimalPart = FALSE; } else { $integerPart = substr($numberToParse, $positionOfFirstDigit, $positionOfDecimalSeparator - $positionOfFirstDigit); $decimalPart = substr($numberToParse, $positionOfDecimalSeparator + 1, $positionOfLastDigit - $positionOfDecimalSeparator); } $parsedNumber = (int) preg_replace(self::PATTERN_MATCH_NOT_DIGITS, '', $integerPart); if ($decimalPart !== FALSE) { $decimalPart = (int) preg_replace(self::PATTERN_MATCH_NOT_DIGITS, '', $decimalPart); $parsedNumber = (double) ($parsedNumber . '.' . $decimalPart); } $partBeforeNumber = substr($numberToParse, 0, $positionOfFirstDigit); $partAfterNumber = substr($numberToParse, -(strlen($numberToParse) - $positionOfLastDigit - 1)); if (!empty($parsedFormat['negativePrefix']) && !empty($parsedFormat['negativeSuffix'])) { if (\TYPO3\FLOW3\I18n\Utility::stringEndsWith($partBeforeNumber, $parsedFormat['negativePrefix']) && \TYPO3\FLOW3\I18n\Utility::stringBeginsWith($partAfterNumber, $parsedFormat['negativeSuffix'])) { $numberIsNegative = TRUE; } } elseif (!empty($parsedFormat['negativePrefix']) && \TYPO3\FLOW3\I18n\Utility::stringEndsWith($partBeforeNumber, $parsedFormat['negativePrefix'])) { $numberIsNegative = TRUE; } elseif (!empty($parsedFormat['negativeSuffix']) && \TYPO3\FLOW3\I18n\Utility::stringBeginsWith($partAfterNumber, $parsedFormat['negativeSuffix'])) { $numberIsNegative = TRUE; } $parsedNumber /= $parsedFormat['multiplier']; if ($numberIsNegative) { $parsedNumber = 0 - $parsedNumber; } return $parsedNumber; }
/** * @test * @dataProvider sampleHaystackStringsAndNeedleStrings */ public function stringIsFoundAtEndingOfAnotherString($haystack, $needle, $comparison) { $expectedResult = $comparison === 'ending' || $comparison === 'both' ? TRUE : FALSE; $result = \TYPO3\FLOW3\I18n\Utility::stringEndsWith($haystack, $needle); $this->assertEquals($expectedResult, $result); }