Back-End

13 jul, 2018

Trabalhando com expressões regulares com o Spatie Regex em PHP

Publicidade

Fala, pessoal!

Continuamos na saga de analisar várias bibliotecas da Spatie. No nosso último artigo, falamos sobre como retornar dados de GPS utilizando a bilbioteca Spatie/Geocoder. No artigo de hoje vamos falar de algo que utilizamos muito, mas ultimamente tem dado um pouco de bug na hora de utilizar, até mesmo pelo PHP não ter um padrão muito intuitivo na utilização: vamos falar de expressões regulares!

A biblioteca Spatie/Regex traz uma maneira muito simples e intuitiva de trabalhar com as expressões regulares, utilizando por trás as funções nativas do PHP, mas trazendo uma nomenclatura muito mais tranquila para quem precisa utilizá-las no dia a dia.

Vamos ver na prática como funciona a biblioteca. Criamos a pasta regex e instalamos ela:

composer require spatie/regex

No arquivo match.php, testaremos alguns modelos de match de expressão regular utilizando uma expressão regular de CPF.

<?php

require_once 'vendor/autoload.php';

use Spatie\Regex\Regex;

$regexCPF = '/^\d{3}\.\d{3}\.\d{3}\-\d{2}$/'; //regex que valida um cpf do seguinte tipo: xxx.xxx.xxx-xx (onde x é um dígito de 0 a 9)

//vamos primeiro verificar os matchs, nesse caso validamos apenas a quantidade de caracteres e tipo em um CPF

var_dump(Regex::match($regexCPF, '111.111.111-11')->hasMatch()); //11 números com ponto e hífen, deve retornar true
print(Regex::match($regexCPF, '111.111.111-11')->result()); //11 números com ponto e hífen, deve retornar o valor
echo (PHP_EOL); //apenas para pular linha rs
var_dump(Regex::match($regexCPF, '1111111111')->hasMatch()); //10 números sem ponto e hífen, deve retornar false
var_dump(Regex::match($regexCPF, '11.111.1111.11-11')->result()); //13 números com ponto e hífen em lugar errado, o retorno é nulo

Vamos testar também como funcionaria um matchAll:

<?php

require_once 'vendor/autoload.php';

use Spatie\Regex\Regex;

$regexTag = '|<[^>]+>(.*)</[^>]+>|U'; //regex que encontra tags dentro de um texto

//vamos validar os regex

var_dump(Regex::matchAll($regexTag, '<br>Ola</br><span>vamos</span><p>la</p>?')->hasMatch()); //Temos "Ola", "vamos" e "la" entre tags, a "?" está fora, logo não entra, retornará true
var_dump(Regex::matchAll($regexTag, '<br>Ola</br><span>vamos</span><p>la</p>?')->results()); //Temos "Ola", "vamos" e "la" entre tags, a "?" está fora, logo não entra, retornará um array com 3 objetos
echo (PHP_EOL); //apenas para pular linha rs
var_dump(Regex::matchAll($regexTag, 'tudo bom?')->hasMatch()); //Não existem tags, retorna false
var_dump(Regex::matchAll($regexTag, 'venhaaaa')->results()); //Não existem tags, o retorno será um array vazio
$ php matchAll.php
bool(true)
array(3) {
  [0]=>
  object(Spatie\Regex\MatchResult)#4 (4) {
    ["pattern":protected]=>
    string(22) "|<[^>]+>(.*)</[^>]+>|U"
    ["subject":protected]=>
    string(40) "<br>Ola</br><span>vamos</span><p>la</p>?"
    ["hasMatch":protected]=>
    bool(true)
    ["matches":protected]=>
    array(2) {
      [0]=>
      string(12) "<br>Ola</br>"
      [1]=>
      string(3) "Ola"
    }
  }
  [1]=>
  object(Spatie\Regex\MatchResult)#5 (4) {
    ["pattern":protected]=>
    string(22) "|<[^>]+>(.*)</[^>]+>|U"
    ["subject":protected]=>
    string(40) "<br>Ola</br><span>vamos</span><p>la</p>?"
    ["hasMatch":protected]=>
    bool(true)
    ["matches":protected]=>
    array(2) {
      [0]=>
      string(18) "<span>vamos</span>"
      [1]=>
      string(5) "vamos"
    }
  }
  [2]=>
  object(Spatie\Regex\MatchResult)#6 (4) {
    ["pattern":protected]=>
    string(22) "|<[^>]+>(.*)</[^>]+>|U"
    ["subject":protected]=>
    string(40) "<br>Ola</br><span>vamos</span><p>la</p>?"
    ["hasMatch":protected]=>
    bool(true)
    ["matches":protected]=>
    array(2) {
      [0]=>
      string(9) "<p>la</p>"
      [1]=>
      string(2) "la"
    }
  }
}

bool(false)
array(0) {
}

Também podemos utilizar o regex replace:

<?php

require_once 'vendor/autoload.php';

use Spatie\Regex\Regex;

$regexTag = '|<[^>]+>(.*)</[^>]+>|U'; //regex que encontra tags dentro de um texto

//vamos trocar as tags

echo(Regex::replace($regexTag, '<pokemao>', '<br>Ola</br><span>vamos</span><p>la</p>?')->result()); //Iremos trocar todas as tags e seu conteudo pela tag <pokemao>
echo (PHP_EOL); //apenas para pular linha rs
echo(Regex::replace($regexTag, '', '<br>Ola</br><span>vamos</span><p>la</p>?')->result()); //Iremos trocar todas as tags e seu conteudo por vazio

Eu achei que ficou bem mais fácil a utilização, bem como a ordem dos parâmetros. Espero que você tenha gostado e possa utilizar em suas próximas integrações.