For numbers, "e" is used in the middle of these 5 cases:
- Between dozens and units, from 21 to 99.
- Between hundreds and dozens or units, from 101 to 999.
- Between thousands and tens or units
(Examples: two thousand and thirty, five thousand and eight).
- Between thousands and hundreds, only if there are no tens or units
(Example: eight thousand and four hundred).
- Between millions and tens or units
(Example: two million thirty-one).
We can use a regular expression to find the position where there should be an "and". regex101.com
/
# Definição de ordens
(?(DEFINE)(?P<unidades> um|dois|tr[eê]s|quatro|cinco|meia|se(?:is|te)|oito|nove ))
(?(DEFINE)(?P<dezenas_dez> d(?:ez(?:e(?:nove|sse(?:is|te))|oito)?|oze)|onze|treze|catorze|quinze ))
(?(DEFINE)(?P<dezenas_exceto_dez> vinte|trinta|(?:quar|cinqu|se(?:ss|t)|oit|nov)enta ))
(?(DEFINE)(?P<dezenas> (?P>dezenas_dez)|(?P>dezenas_exceto_dez) ))
(?(DEFINE)(?P<dezenas_ou_unidades> (?P>dezenas)|(?P>unidades) ))
(?(DEFINE)(?P<centenas> ce(?:m|ntos?)|(?:qu(?:atroc|inh)|(?:du|tre|se(?:is|te)|oito|nove)[cz])entos? ))
(?(DEFINE)(?P<mil> mil ))
(?(DEFINE)(?P<milhoes> (?:(?:[mb]|tr)i|qu(?:atri|inqua))lh(?:[aã]o|[oõ]es) ))
(?(DEFINE)(?P<s> [ ]+ ))
(?(DEFINE)(?P<e> e(?P>s) ))
#Regras
\b(?:
#1. Entre dezenas>=20 e unidades
(?P>dezenas_exceto_dez)(?P>s)(?=(?P>unidades)\b)
|
#2. Entre centenas e dezenas ou unidades
(?P>centenas)(?P>s)(?=(?P>dezenas_ou_unidades)\b)
|
#3-4. Entre milhares...
(?P>mil)(?P>s)(?=
(?:
#3. ... e dezenas ou unidades
(?P>dezenas_ou_unidades)
|
#4. ... e centenas, somente se não houver dezenas ou unidades
(?P>centenas)(?!(?P>s)(?P>e)?(?P>dezenas_ou_unidades)\b)
)
\b
)
|
#5. Entre milhões e dezenas ou unidades (que não sejam unidades ou dezenas de milhões ou unidades ou dezenas de milhares)
(?P>milhoes)(?P>s)(?=
(?P>dezenas_ou_unidades)(?!(?P>s)(?P>e)?(?:(?P>unidades)(?P>s)(?P>e)?)?(?:(?P>milhoes)|(?P>mil))\b)\b
)
)
\b
#Reset
\K
/iux
Or, in a single line, no comments:
/(?(DEFINE)(?P<unidades>um|dois|tr[eê]s|quatro|cinco|meia|se(?:is|te)|oito|nove))(?(DEFINE)(?P<dezenas_dez>d(?:ez(?:e(?:nove|sse(?:is|te))|oito)?|oze)|onze|treze|catorze|quinze))(?(DEFINE)(?P<dezenas_exceto_dez>vinte|trinta|(?:quar|cinqu|se(?:ss|t)|oit|nov)enta))(?(DEFINE)(?P<dezenas>(?P>dezenas_dez)|(?P>dezenas_exceto_dez)))(?(DEFINE)(?P<dezenas_ou_unidades>(?P>dezenas)|(?P>unidades)))(?(DEFINE)(?P<centenas>ce(?:m|ntos?)|(?:qu(?:atroc|inh)|(?:du|tre|se(?:is|te)|oito|nove)[cz])entos?))(?(DEFINE)(?P<mil>mil))(?(DEFINE)(?P<milhoes>(?:(?:[mb]|tr)i|qu(?:atri|inqua))lh(?:[aã]o|[oõ]es)))(?(DEFINE)(?P<s> +))(?(DEFINE)(?P<e>e(?P>s)))\b(?:(?P>dezenas_exceto_dez)(?P>s)(?=(?P>unidades)\b)|(?P>centenas)(?P>s)(?=(?P>dezenas_ou_unidades)\b)|(?P>mil)(?P>s)(?=(?:(?P>dezenas_ou_unidades)|(?P>centenas)(?!(?P>s)(?P>e)?(?P>dezenas_ou_unidades)\b))\b)|(?P>milhoes)(?P>s)(?=(?P>dezenas_ou_unidades)(?!(?P>s)(?P>e)?(?:(?P>unidades)(?P>s)(?P>e)?)?(?:(?P>milhoes)|(?P>mil))\b)\b))\b\K/iux
Replacing by the text: 'e '
.
I set the limit for quinquallon (10 18). You can complete it, or use:
(?(DEFINE)(?P<milhoes>\w+lh(?:[aã]o|[oõ]es)))
as a general case.
Code:
<?php // /q/257031/53463
$re = '/
# Definição de ordens
(?(DEFINE)(?P<unidades> um|dois|tr[eê]s|quatro|cinco|meia|se(?:is|te)|oito|nove ))
(?(DEFINE)(?P<dezenas_dez> d(?:ez(?:e(?:nove|sse(?:is|te))|oito)?|oze)|onze|treze|catorze|quinze ))
(?(DEFINE)(?P<dezenas_exceto_dez> vinte|trinta|(?:quar|cinqu|se(?:ss|t)|oit|nov)enta ))
(?(DEFINE)(?P<dezenas> (?P>dezenas_dez)|(?P>dezenas_exceto_dez) ))
(?(DEFINE)(?P<dezenas_ou_unidades> (?P>dezenas)|(?P>unidades) ))
(?(DEFINE)(?P<centenas> ce(?:m|ntos?)|(?:qu(?:atroc|inh)|(?:du|tre|se(?:is|te)|oito|nove)[cz])entos? ))
(?(DEFINE)(?P<mil> mil ))
(?(DEFINE)(?P<milhoes> (?:(?:[mb]|tr)i|qu(?:atri|inqua))lh(?:[aã]o|[oõ]es) ))
(?(DEFINE)(?P<s> [ ]+ ))
(?(DEFINE)(?P<e> e(?P>s) ))
#Regras
\b(?:
#1. Entre dezenas>=20 e unidades
(?P>dezenas_exceto_dez)(?P>s)(?=(?P>unidades)\b)
|
#2. Entre centenas e dezenas ou unidades
(?P>centenas)(?P>s)(?=(?P>dezenas_ou_unidades)\b)
|
#3-4. Entre milhares...
(?P>mil)(?P>s)(?=
(?:
#3. ... e dezenas ou unidades
(?P>dezenas_ou_unidades)
|
#4. ... e centenas, somente se não houver dezenas ou unidades
(?P>centenas)(?!(?P>s)(?P>e)?(?P>dezenas_ou_unidades)\b)
)
\b
)
|
#5. Entre milhões e dezenas ou unidades (que não sejam unidades ou dezenas de milhões ou unidades ou dezenas de milhares)
(?P>milhoes)(?P>s)(?=
(?P>dezenas_ou_unidades)(?!(?P>s)(?P>e)?(?:(?P>unidades)(?P>s)(?P>e)?)?(?:(?P>milhoes)|(?P>mil))\b)\b
)
)
\b
#Reset
\K
/iux';
$subst = 'e ';
//Exemplos
$teste = [
'vinte cinco',
'vinte cinco mil',
'vinte cinco reais',
'vinte cinco reais e vinte cinco centavos',
'aaa bbb ccc',
'dois mil trezentos',
'dois mil trezentos quarenta cinco',
'dois milhões trinta um',
'dois milhões trinta um mil',
'dois milhões trinta mil',
'dois milhões trinta um',
'cento vinte três milhões quatrocentos cinquenta seis mil setecentos oitenta nove'
];
//Substituir
$resultado = preg_replace($re, $subst, $teste);
//Mostrar em uma única matriz
$resultado_final = array_combine( $teste, $resultado);
var_export($resultado_final);
Upshot:
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',
)
ideone.
And if the string is
aaa bbb ccc
going twoe
? ta vague the criterion.– rray
You’ll always have this fixed size
aaa aaa
?– UzumakiArtanis
yes this can happen: aaa bbb ccc => aaa and bbb and ccc
– alexjosesilva
the size will land 6 decimal places
– alexjosesilva
That solves?
$str = 'aaa bbb ccc '; echo str_replace(' ', ' e ', $str);
– rray
perfect...right answer
– alexjosesilva
can answer the question. for you to earn your points!!
– alexjosesilva
Sure? will return
vinte E cinco E reais
– rray
here is working perfectly
– alexjosesilva
It’s looking like a case of XY problem. Wouldn’t it be better if you asked the question what problem you need to solve?
– Woss
As noticed by Anderson, you want to open the coconut or you want to know how to replace the sieve automatically after firing the tank?
– Jefferson Quesado
The @rray solution to
vinte cinco mil
would go badlyvinte e cinco e mil
and tovinte cinco reais e vinte cinco centavos
would-bevinte e cinco e reais e e e vinte e cinco e centavos
– user60252