protected static function getDecimalParseRegex(AgaviLocale $locale = null)
 {
     static $patternCache = array();
     if ($locale) {
         $localeId = $locale->getIdentifier();
     } else {
         $localeId = '';
     }
     if (isset($patternCache[$localeId])) {
         return $patternCache[$localeId];
     }
     if ($locale) {
         $decimalFormats = $locale->getDecimalFormats();
         $groupingSeparator = $locale->getNumberSymbolGroup();
         $decimalSeparator = $locale->getNumberSymbolDecimal();
         $minusSign = $locale->getNumberSymbolMinusSign();
     } else {
         $decimalFormats = array('#,##0.###');
         $groupingSeparator = ',';
         $decimalSeparator = '.';
         $minusSign = '-';
     }
     $patterns = array();
     foreach ($decimalFormats as $decimalFormatList) {
         $decimalFormatList = explode(';', $decimalFormatList, 2);
         if (count($decimalFormatList) == 1) {
             // no pattern for negative numbers
             // we need a copy of the format with a minus prefix
             $decimalFormatList[1] = '-' . $decimalFormatList[0];
         }
         foreach (array(true, false) as $withFraction) {
             foreach ($decimalFormatList as $decimalFormat) {
                 // we need to make three parts: number, decimal part and minus sign
                 $decimalFormatChunks = preg_split('/([\\.\\-])/', $decimalFormat, 0, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
                 // there is a minus sign at the beginning or end! find it!
                 $pastDecimalSeparator = false;
                 foreach ($decimalFormatChunks as &$decimalFormatChunk) {
                     if ($decimalFormatChunk == '-') {
                         // always allow "-" in addition to the minus sign supplied by the locale. we do this because some locales (e.g. da, fa, se, sv) have U+2212 (the "real" minus sign) defined in the locale data, but no human can really type that character on their keyboard. consider it lenient parsing ;) see ticket #1293
                         $decimalFormatChunk = '(?P<minus>' . preg_quote($minusSign, '#') . '|-)';
                     } elseif ($decimalFormatChunk == '.') {
                         $pastDecimalSeparator = true;
                         if ($withFraction) {
                             $decimalFormatChunk = preg_quote($decimalSeparator, '#');
                         } else {
                             $decimalFormatChunk = '';
                         }
                     } else {
                         $decimalFormatChunk = preg_replace('/[#0,]+/u', '[\\d' . preg_quote($groupingSeparator, '#') . ']*', $decimalFormatChunk);
                         if (!$pastDecimalSeparator) {
                             if ($withFraction) {
                                 $decimalFormatChunk = '(?P<num>(?=[\\d,]*\\d)' . $decimalFormatChunk . '(\\d|' . $decimalFormatChunk . '(?=\\.[\\d,]*\\d)))?';
                             } else {
                                 $decimalFormatChunk = '(?P<num>(?=[\\d,]*\\d)' . $decimalFormatChunk . '\\d)';
                             }
                         } else {
                             if ($withFraction) {
                                 $decimalFormatChunk = '(?P<dec>' . $decimalFormatChunk . '\\d)?';
                             } else {
                                 $decimalFormatChunk = '';
                             }
                         }
                     }
                 }
                 $patterns[] = implode('', $decimalFormatChunks);
             }
         }
     }
     return $patternCache[$localeId] = '#(?J)^(' . implode('|', $patterns) . ')#u';
 }