/framework/Support/lib/Horde/Support/Numerizer/Locale/Base.php

https://github.com/finger2000/horde · PHP · 164 lines · 120 code · 14 blank · 30 comment · 4 complexity · 4818721a38e7750dba3c987995f83996 MD5 · raw file

  1. <?php
  2. /**
  3. * Copyright 2010-2011 Horde LLC (http://www.horde.org/)
  4. *
  5. * @author Chuck Hagenbuch <chuck@horde.org>
  6. * @license http://www.horde.org/licenses/bsd BSD
  7. * @category Horde
  8. * @package Support
  9. */
  10. /**
  11. * @author Chuck Hagenbuch <chuck@horde.org>
  12. * @license http://www.horde.org/licenses/bsd BSD
  13. * @category Horde
  14. * @package Support
  15. */
  16. class Horde_Support_Numerizer_Locale_Base
  17. {
  18. public $DIRECT_NUMS = array(
  19. 'eleven' => '11',
  20. 'twelve' => '12',
  21. 'thirteen' => '13',
  22. 'fourteen' => '14',
  23. 'fifteen' => '15',
  24. 'sixteen' => '16',
  25. 'seventeen' => '17',
  26. 'eighteen' => '18',
  27. 'nineteen' => '19',
  28. 'ninteen' => '19', // Common mis-spelling
  29. 'zero' => '0',
  30. 'one' => '1',
  31. 'two' => '2',
  32. 'three' => '3',
  33. 'four(\W|$)' => '4$1', // The weird regex is so that it matches four but not fourty
  34. 'five' => '5',
  35. 'six(\W|$)' => '6$1',
  36. 'seven(\W|$)' => '7$1',
  37. 'eight(\W|$)' => '8$1',
  38. 'nine(\W|$)' => '9$1',
  39. 'ten' => '10',
  40. '\ba[\b^$]' => '1', // doesn't make sense for an 'a' at the end to be a 1
  41. );
  42. public $TEN_PREFIXES = array(
  43. 'twenty' => 20,
  44. 'thirty' => 30,
  45. 'fourty' => 40,
  46. 'fifty' => 50,
  47. 'sixty' => 60,
  48. 'seventy' => 70,
  49. 'eighty' => 80,
  50. 'ninety' => 90,
  51. );
  52. public $BIG_PREFIXES = array(
  53. 'hundred' => 100,
  54. 'thousand' => 1000,
  55. 'million' => 1000000,
  56. 'billion' => 1000000000,
  57. 'trillion' => 1000000000000,
  58. );
  59. public function numerize($string)
  60. {
  61. // preprocess
  62. $string = $this->_splitHyphenatedWords($string);
  63. $string = $this->_hideAHalf($string);
  64. $string = $this->_directReplacements($string);
  65. $string = $this->_replaceTenPrefixes($string);
  66. $string = $this->_replaceBigPrefixes($string);
  67. $string = $this->_fractionalAddition($string);
  68. return $string;
  69. }
  70. /**
  71. * will mutilate hyphenated-words but shouldn't matter for date extraction
  72. */
  73. protected function _splitHyphenatedWords($string)
  74. {
  75. return preg_replace('/ +|([^\d])-([^d])/', '$1 $2', $string);
  76. }
  77. /**
  78. * take the 'a' out so it doesn't turn into a 1, save the half for the end
  79. */
  80. protected function _hideAHalf($string)
  81. {
  82. return str_replace('a half', 'haAlf', $string);
  83. }
  84. /**
  85. * easy/direct replacements
  86. */
  87. protected function _directReplacements($string)
  88. {
  89. foreach ($this->DIRECT_NUMS as $dn => $dn_replacement) {
  90. $string = preg_replace("/$dn/i", $dn_replacement, $string);
  91. }
  92. return $string;
  93. }
  94. /**
  95. * ten, twenty, etc.
  96. */
  97. protected function _replaceTenPrefixes($string)
  98. {
  99. foreach ($this->TEN_PREFIXES as $tp => $tp_replacement) {
  100. $string = preg_replace_callback(
  101. "/(?:$tp)( *\d(?=[^\d]|\$))*/i",
  102. create_function(
  103. '$m',
  104. 'return ' . $tp_replacement . ' + (isset($m[1]) ? (int)$m[1] : 0);'
  105. ),
  106. $string);
  107. }
  108. return $string;
  109. }
  110. /**
  111. * hundreds, thousands, millions, etc.
  112. */
  113. protected function _replaceBigPrefixes($string)
  114. {
  115. foreach ($this->BIG_PREFIXES as $bp => $bp_replacement) {
  116. $string = preg_replace_callback(
  117. '/(\d*) *' . $bp . '/i',
  118. create_function(
  119. '$m',
  120. 'return ' . $bp_replacement . ' * (int)$m[1];'
  121. ),
  122. $string);
  123. $string = $this->_andition($string);
  124. }
  125. return $string;
  126. }
  127. protected function _andition($string)
  128. {
  129. while (true) {
  130. if (preg_match('/(\d+)( | and )(\d+)(?=[^\w]|$)/i', $string, $sc, PREG_OFFSET_CAPTURE)) {
  131. if (preg_match('/and/', $sc[2][0]) || (strlen($sc[1][0]) > strlen($sc[3][0]))) {
  132. $string = substr($string, 0, $sc[1][1]) . ((int)$sc[1][0] + (int)$sc[3][0]) . substr($string, $sc[3][1] + strlen($sc[3][0]));
  133. continue;
  134. }
  135. }
  136. break;
  137. }
  138. return $string;
  139. }
  140. protected function _fractionalAddition($string)
  141. {
  142. return preg_replace_callback(
  143. '/(\d+)(?: | and |-)*haAlf/i',
  144. create_function(
  145. '$m',
  146. 'return (string)((float)$m[1] + 0.5);'
  147. ),
  148. $string);
  149. }
  150. }