fork download
  1. <?php
  2.  
  3. // https://pt.stackoverflow.com/q/257031/53463
  4.  
  5. $re = '/
  6. # Definição de ordens
  7. (?(DEFINE)(?P<unidades> um|dois|tr[eê]s|quatro|cinco|meia|se(?:is|te)|oito|nove ))
  8. (?(DEFINE)(?P<dezenas_dez> d(?:ez(?:e(?:nove|sse(?:is|te))|oito)?|oze)|onze|treze|catorze|quinze ))
  9. (?(DEFINE)(?P<dezenas_exceto_dez> vinte|trinta|(?:quar|cinqu|se(?:ss|t)|oit|nov)enta ))
  10. (?(DEFINE)(?P<dezenas> (?P>dezenas_dez)|(?P>dezenas_exceto_dez) ))
  11. (?(DEFINE)(?P<dezenas_ou_unidades> (?P>dezenas)|(?P>unidades) ))
  12. (?(DEFINE)(?P<centenas> ce(?:m|ntos?)|(?:qu(?:atroc|inh)|(?:du|tre|se(?:is|te)|oito|nove)[cz])entos? ))
  13. (?(DEFINE)(?P<mil> mil ))
  14. (?(DEFINE)(?P<milhoes> (?:(?:[mb]|tr)i|qu(?:atri|inqua))lh(?:[aã]o|[oõ]es) ))
  15. (?(DEFINE)(?P<s> [ ]+ ))
  16. (?(DEFINE)(?P<e> e(?P>s) ))
  17.  
  18.  
  19. #Regras
  20. \b(?:
  21.  
  22. #1. Entre dezenas>=20 e unidades
  23. (?P>dezenas_exceto_dez)(?P>s)(?=(?P>unidades)\b)
  24. |
  25. #2. Entre centenas e dezenas ou unidades
  26. (?P>centenas)(?P>s)(?=(?P>dezenas_ou_unidades)\b)
  27. |
  28. #3-4. Entre milhares...
  29. (?P>mil)(?P>s)(?=
  30. (?:
  31. #3. ... e dezenas ou unidades
  32. (?P>dezenas_ou_unidades)
  33. |
  34. #4. ... e centenas, somente se não houver dezenas ou unidades
  35. (?P>centenas)(?!(?P>s)(?P>e)?(?P>dezenas_ou_unidades)\b)
  36. )
  37. \b
  38. )
  39. |
  40. #5. Entre milhões e dezenas ou unidades (que não sejam unidades ou dezenas de milhões ou unidades ou dezenas de milhares)
  41. (?P>milhoes)(?P>s)(?=
  42. (?P>dezenas_ou_unidades)(?!(?P>s)(?P>e)?(?:(?P>unidades)(?P>s)(?P>e)?)?(?:(?P>milhoes)|(?P>mil))\b)\b
  43.  
  44. )
  45.  
  46. )
  47. \b
  48.  
  49. #Reset
  50. \K
  51.  
  52. /iux';
  53.  
  54. $subst = 'e ';
  55.  
  56.  
  57. //Exemplos
  58. $teste = [
  59. 'vinte cinco',
  60. 'vinte cinco mil',
  61. 'vinte cinco reais',
  62. 'vinte cinco reais e vinte cinco centavos',
  63. 'aaa bbb ccc',
  64. 'dois mil trezentos',
  65. 'dois mil trezentos quarenta cinco',
  66. 'dois milhões trinta um',
  67. 'dois milhões trinta um mil',
  68. 'dois milhões trinta mil',
  69. 'dois milhões trinta um',
  70. 'cento vinte três milhões quatrocentos cinquenta seis mil setecentos oitenta nove'
  71. ];
  72.  
  73. //Substituir
  74. $resultado = preg_replace($re, $subst, $teste);
  75.  
  76.  
  77. //Mostrar em uma única matriz
  78. $resultado_final = array_combine( $teste, $resultado);
  79. var_export($resultado_final);
Success #stdin #stdout 0.01s 82944KB
stdin
Standard input is empty
stdout
array (
  'vinte cinco' => 'vinte e cinco',
  'vinte cinco mil' => 'vinte e cinco mil',
  'vinte cinco reais' => 'vinte e cinco reais',
  'vinte cinco reais e vinte cinco centavos' => 'vinte e cinco reais e vinte e cinco centavos',
  'aaa bbb ccc' => 'aaa bbb ccc',
  'dois mil trezentos' => 'dois mil e trezentos',
  'dois mil trezentos quarenta cinco' => 'dois mil trezentos e quarenta e cinco',
  'dois milhões trinta um' => 'dois milhões e trinta e um',
  'dois milhões trinta um mil' => 'dois milhões trinta e um mil',
  'dois milhões trinta mil' => 'dois milhões trinta mil',
  'cento vinte três milhões quatrocentos cinquenta seis mil setecentos oitenta nove' => 'cento e vinte e três milhões quatrocentos e cinquenta e seis mil setecentos e oitenta e nove',
)