Ser Programador

Como encontrar uma string dentro de outra string com PHP

Neste artigo vamos entender como utilizar a função strpos do PHP.


Hoje falaremos de algo bem simples, porém muito útil do dia a dia de um desenvolvedor.

Volta e meia, quando trabalhamos com dados em formato de texto nos deparamos com a necessidade de pesquisar dentro de um texto existente por um termo qualquer, para então efetuarmos alguma tomada de decisão. Isso é bem simples de ser feito através da função strpos do PHP.



A função strpos retorna o número da posição (inicia-se em zero) do texto em que a string procurada é encontrada; caso não seja encontrada, FALSE é retornado.

Esta função é case-sensitive, sendo assim, caracteres maiúsculos são tomados como diferentes de minúsculos. Caso queira ignorar assa diferença entre os caracteres, você deve utilizar a função stripos.

O número da posição encontrada pela função strpos será sempre da primeira ocorrência, dessa forma, caso precisar pesquisar por mais ocorrências é necessária uma abordagem através de outras funções como strrpos que retorna a posição da última ocorrência (também é case-sensitive), ou strripos que tem o mesmo funcionamento da strrpos, porém é case-insensitive (não diferencia caracteres maiúsculos de minúsculos).


Vamos aos detalhes da função strpos com um exemplo:

        <?php
        	$stringBase		= 'O Ser Programador te ajuda a obter sucesso!';
            $stringPesquisa	= 'sucesso';
            
            echo strpos($stringBase, $stringPesquisa);
            
    

A função strpos recebe dois parâmetros:

  1. a string base na qual será efetuada a pesquisa;
  2. o termo que desejamos pesquisar na string base;

O exemplo acima irá apresentar em tela a posição 35.


Agora, vamos abordar um "caso de uso" como ilustração.

Vamos supor que recebemos através de um arquivo ".txt", linhas de texto com diversos dados dos quais o único que nos importa é o valor monetário para que possamos apresentar o valor total do lote de dados que recebemos. Tomaremos como regra de negócio que o valor é formatado por oito dígitos preenchidos com zeros à esquerda e os dois últimos dígitos são casas decimais.

Vejamos o exemplo do lote de dados:

        XYZTESTEDEDADOSINVESTIMENTOR$100000992020
        ABCTESTEDEDADOSINVESTIMENTOR$599000852020
        KLMTESTEDEDADOSINVESTIMENTOR$799777332020
        QWRTESTEDEDADOSINVESTIMENTOR$000597272020
	

A partir desta estrutura de dados podemos sugerir duas formas de trabalhar para extrair os dados monetários:

  1. todos os dados seguem um padrão delimitado de quantidade de caracteres, portanto sabemos sempre qual será a posição do valor monetário. Nesta hipótese bastaria aplicarmos a função substr do PHP;
  2. os dados não seguem um padrão delimitado de quantidade de caracteres, assim a posição do valor monetário pode mudar de acordo com a quantidade de caracteres existentes no registro. Trabalharemos com esta hipótese para satisfazer a finalidade do nosso exercício;

Vamos ao exemplo prático:

        <?php
            $linhasDoArquivo = explode("\n", file_get_contents("txt.txt"));
            
            echo '<pre>';
            print_r($linhasDoArquivo);
            echo '</pre>';
            
            $valorTotal = 0;
            foreach ($linhasDoArquivo as $linha) {
                $valorDaLinha = (int)substr($linha, strpos($linha, 'R$') + 2, 8) / 100;
				echo '<p>O valor encontrado foi: R$ ' . number_format($valorDaLinha, 2, ',', '.') . '</p>';
                
                $valorTotal += $valorDaLinha;
            }
            
            echo '<p>O valor total é: R$' . number_format($valorTotal, 2, ',', '.') . '</p>';
            
    

O fizemos foi:

Na linha 2, utilizamos a função file_get_contents para obter o conteúdo do arquivo .txt, e fornecemos o retorno dessa função como parâmetro para a função explode com separador de quebra de linha "\n", para obter um array com as linhas do arquivo;

Nas linhas 4, 5 e 6, printamos em formato cru (sem formatação) o array obtido, através da tag HTML pre;

Na linha 8, instanciamos a variável $valorTotal que receberá a somatória dos valores monetários. Instanciamos ela aqui, fora do foreach para que não tenhamos um erro caso o arquivo .txt esteja vazio e o foreach não seja executado;

Na linha 9, abrimos o laço de repetição foreach para percorrer o array obtido dos dados do arquivo .txt;

Na linha 10, primeiro encontramos a posição do símbolo de moeda (R$) com a função strpos. Então somamos com 2 para obter a posição de início do valor numérico;

Ainda na linha 10, depois de encontrar a posição inicial do valor numérico, fornecemos esse dado como segundo parâmetro para função substr, juntamente da linha do arquivo, e da quantidade de caracteres (8) do valor monetário;

Continuando na linha 10, após receber a string numérica de oito caracteres extraída da linha do arquivo, convertemos a string em formato inteiro, para eliminar os zeros à esquerda e obter um dado em formato numérico. Depois fazemos a divisão desse número por 100 para converter o número inteiro em decimal (formato float), e assim termos corretamente um valor monetário armazenado na variável $valorDaLinha;

Na linha 11, utilizamos a função number_format para apresentarmos um número legível aos padrões do Brasil, com duas casas decimais, vírgula como separador decimal e ponto como separador de casas de milhar;

Na linha 13, com o uso do "+=" (sinal de mais e igual), somamos o valor float armazenado na variável $valorDaLinha com o valor já existente da variável $valorTotal, e o resultado é armazenado na mesma variável $valorTotal;

Por fim, na linha 16, após fecharmos o laço de repetição foreach, apresentamos o valor total da somatória;


Como resultado teremos o seguinte:

        Array
        (
            [0] => XYZTESTEDEDADOSINVESTIMENTOR$100000992020
            [1] => ABCTESTEDEDADOSINVESTIMENTOR$599000852020
            [2] => KLMTESTEDEDADOSINVESTIMENTOR$799777332020
            [3] => QWRTESTEDEDADOSINVESTIMENTOR$000597272020
        )
        O valor encontrado foi: R$ 100.000,99
        
        O valor encontrado foi: R$ 599.000,85
        
        O valor encontrado foi: R$ 799.777,33
        
        O valor encontrado foi: R$ 597,27
        
        O valor total é: R$1.499.376,44