How to insert a letter between two words in a php string?

Asked

Viewed 132 times

-1

I have to insert a monosyllable between two words inside a PHP string, as in the examples below:

// entrada
string=> vinte cinco 
// saída
string=> vinte e cinco

// entrada
string=> vinte cinco mil 
// saída
string=> vinte e cinco  mil

// entrada
string=> vinte cinco reais e vinte cinco centavos
// saída 
string=> vinte e cinco reais e vinte e cinco centavos
  • And if the string is aaa bbb ccc going two e? ta vague the criterion.

  • You’ll always have this fixed size aaa aaa?

  • yes this can happen: aaa bbb ccc => aaa and bbb and ccc

  • the size will land 6 decimal places

  • That solves? $str = 'aaa bbb ccc '; echo str_replace(' ', ' e ', $str);

  • 1

    perfect...right answer

  • can answer the question. for you to earn your points!!

  • Sure? will return vinte E cinco E reais

  • here is working perfectly

  • 6

    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?

  • 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?

  • 1

    The @rray solution to vinte cinco mil would go badly vinte e cinco e mil and to vinte cinco reais e vinte cinco centavos would-be vinte e cinco e reais e e e vinte e cinco e centavos

Show 7 more comments

2 answers

2

example - ideone

$result="";

$str = 'vinte cinco reais e vinte cinco centavos'; 

/*****Opcional, para prevenir entradas adversas****/
//Primeiro usa o trim() para limpar os espaços do início e do final da string.
//preg_replace() para remover os espaços duplicados.
//O caracter de escape \s significa "qualquer espaço em branco".
//A notação (?=) é usada para realizar pesquisa adiante. Na prática ele significa "qualquer espaço que é seguido por outro espaço". Isso remove os duplicados, deixando apenas um espaço em branco.
$str=trim(preg_replace('/\s(?=\s)/', '', $str));
/*****fim, para prevenir entradas adversas****/

//substitue todos os caracteres " e " por " " na string
$str = str_replace(" e ", " ", $str);

//cria array
$a = explode(" ",$str);

//itera o array e concatena " e " quando necessário
for($i=0; $i < count($a); $i++){

      //interrompe o laço for para evitar o erro Notice: Undefined offset para "$a[$i+1]" caso fosse realizado a ultima iteraçao
      if($i == count($a)-1){
        $result = $result . $a[$i];
        break;
      }

      //concatena  " e " quando necessário
      if (($a[$i+1]=="reais")||($a[$i+1]=="mil")||($a[$i+1]=="centavos")){
        $result = $result . $a[$i] . " ";
      }else{
        $result = $result . $a[$i] . " e ";
      }

}

echo $result;

to answer @R.Santos' question `

one hundred ten? What would that look like?`

just include this condition further ($a[$i+1]=="cento") along those lines

if (($a[$i+1]=="reais")||($a[$i+1]=="mil")||($a[$i+1]=="centavos")){

thus remaining

if (($a[$i+1]=="reais")||($a[$i+1]=="mil")||($a[$i+1]=="centavos")||($a[$i+1]=="cento")){

result - ideone

  • one hundred ten? What would that look like?

  • I haven’t tried it because I didn’t think of it but I think it would be mil e cento e dez

  • https://answall.com/questions/257099/erro-na-sa%C3%Adda-da-data-by-full. I believe that’s what he wants, actually he doesn’t even have cento on his list only cem which turns out to be a mistake on his part. but I believe it will be necessary to include this option at least 1210

  • it is, three hundred, four hundred etcc million billion etccc dai gets bad. But nothing that with a little more work gets to the desired

  • That’s right, bilhões is already another option that not only has milhões

  • @R.Santos, to answer his mil cento dez? Como ficaria? see https://ideone.com/NHZxB9

Show 2 more comments

1


For numbers, "e" is used in the middle of these 5 cases:

  1. Between dozens and units, from 21 to 99.
  2. Between hundreds and dozens or units, from 101 to 999.
  3. Between thousands and tens or units
    (Examples: two thousand and thirty, five thousand and eight).
  4. Between thousands and hundreds, only if there are no tens or units
    (Example: eight thousand and four hundred).
  5. 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.

  • sextillion, septillion, octillion, nonillion, decillion, ........ tredecillion, etc.... ? It is incomplete :)

  • I just wanted to play with you. The code I understood, otherwise I wouldn’t have left the sextilhões house in fun

  • Thanks @Leo. I added a note about the limit.

  • 2

    This figure only for those who live in Brasilia, hehehe, +1 data

  • The code is complete. Almost a TCC...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.