Grupos de Captura Regex

Resumo : neste tutorial, você aprenderá como usar grupos de captura de regex para agrupar e capturar partes de uma partida.

Introdução aos grupos de captura de regex

Suponha que você tenha um URI com o seguinte formato:

'posts/25'Linguagem de código:  PHP  ( php )

O URI possui um nome de recurso ( posts) e um id ( 25). O nome do recurso é uma string, enquanto o ID do recurso é um número inteiro.

Para corresponder a esse URI, você pode usar o seguinte padrão:

\w+/\d+Linguagem de código:  PHP  ( php )

O seguinte descreve o padrão:

  • \w+– comece com uma ou mais palavras
  • /– contém a barra (/).
  • \d+– termine com um ou mais números

Como o padrão contém a barra ( /), é mais legível usar chaves como delimitadores para formar a expressão regular :

"{\w+/\d+}"Linguagem de código:  PHP  ( php )

O seguinte usa a preg_match()função para corresponder ao URI:

<?php

$uri = 'posts/25';
$pattern = '{\w+/\d+}';

if (preg_match($pattern, $uri, $matches)) {
    print_r($matches);
}Linguagem de código:  PHP  ( php )

Aqui está o resultado:

Array
(
    [0] => posts/25
)Linguagem de código:  PHP  ( php )

Para obter o ID do URI, você pode usar um grupo de captura.

Um grupo de captura permite que você obtenha uma parte da correspondência como um item separado na matriz de resultados.

Para criar um grupo de captura, coloque parte do padrão entre parênteses (...). Por exemplo, para capturar o idURI acima, você pode usar a seguinte expressão regular com um grupo de captura que captura a \d+parte:

'{\w+/(\d+)}'Linguagem de código:  PHP  ( php )

O seguinte mostra o código atualizado com o grupo de captura:

<?php

$uri = 'posts/25';
$pattern = '{\w+/(\d+)}';

if (preg_match($pattern, $uri, $matches)) {
    print_r($matches);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [0] => posts/25
    [1] => 25
)Linguagem de código:  PHP  ( php )

A $matchesmatriz agora inclui a correspondência e o grupo de captura. Além disso, você pode ter vários grupos de captura como este:

<?php

$uri = 'posts/25';
$pattern = '{(\w+)/(\d+)}';

if (preg_match($pattern, $uri, $matches)) {
    print_r($matches);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [0] => posts/25
    [1] => posts
    [2] => 25
)Linguagem de código:  PHP  ( php )

Grupos nomeados Regex

Você pode colocar a ?<name>sintaxe imediatamente após o parêntese de abertura para nomear um grupo de captura. Por exemplo:

<?php

$uri = 'posts/25';
$pattern = '{(?<controller>\w+)/(?<id>\d+)}';

if (preg_match($pattern, $uri, $matches)) {
    print_r($matches);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [0] => posts/25
    [controller] => posts
    [1] => posts
    [id] => 25
    [2] => 25
)Linguagem de código:  PHP  ( php )

Neste exemplo, atribuímos à primeira parte do URI o nome controllere à segunda parte o nome id.

Para obter apenas controllere iddo $matchesarray, você pode passar o $matchesarray para a array_filter()função assim:

<?php

$uri = 'posts/25';
$pattern = '{(?<controller>\w+)/(?<id>\d+)}';

if (preg_match($pattern, $uri, $matches)) {
    $parts = array_filter($matches, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
    print_r($parts);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [controller] => posts
    [id] => 25
)Linguagem de código:  PHP  ( php )

Observe que as estruturas PHP MVC geralmente usam essa técnica para resolver o URI com um controlador e parâmetros de consulta.

Mais exemplos de grupos de captura de regex

Suponha que você precise corresponder ao seguinte padrão:

controller/year/month/dayLinguagem de código:  PHP  ( php )

E você deseja capturar o controlador, ano, mês e dia.

Para fazer isso, você usa os grupos nomeados para capturar grupos em um padrão como o seguinte:

<?php

// controller/year/month/day
$uri = 'posts/2021/09/12';

$pattern = '{(?<controller>\w+)/(?<year>\d{4})/(?<month>\d{2})/(?<day>\d{2})}';

if (preg_match($pattern, $uri, $matches)) {
    // only get string key
    $parts = array_filter($matches, fn($key) => is_string($key), ARRAY_FILTER_USE_KEY);
    print_r($parts);
}Linguagem de código:  PHP  ( php )

Saída:

Array
(
    [controller] => posts
    [year] => 2021
    [month] => 09
    [day] => 12
)Linguagem de código:  PHP  ( php )

Referência regex capturando grupos em strings de substituição

Suponha que você tenha o nome de uma pessoa na ordem do nome e do sobrenome, por exemplo, 'John Doe'e queira reformatá-lo na ordem inversa, como 'Doe, John':

$name = 'John Doe'; // turns into 'Doe, John'Linguagem de código:  PHP  ( php )

Para corresponder ao formato do nome, você pode usar a seguinte expressão regular:

'{\w+ \w+}'Linguagem de código:  JavaScript  ( javascript )

Para capturar o nome e o sobrenome na matriz de correspondências, você pode colocar o \w+padrão entre parênteses:

'{(\w+) (\w+)}'Linguagem de código:  JavaScript  ( javascript )

A preg_replace()função permite referenciar um grupo de captura pelo seu número usando o $nformato, onde né o número do grupo de captura.

Então, no seguinte padrão:

'{(\w+) (\w+)}'Linguagem de código:  JavaScript  ( javascript )

O $1faz referência ao grupo de captura para o primeiro nome e $2faz referência ao grupo de captura para o sobrenome.

A seguir mostra como usar a preg_replace()função para trocar o nome e o sobrenome e colocar uma vírgula entre eles:

<?php

$name = 'John Doe';
$pattern = '{(\w+) (\w+)}';

echo preg_replace($pattern, '$2, $1', $name);Linguagem de código:  HTML, XML  ( xml )

Saída:

Doe, John

Resumo

  • Use um grupo de captura de regex para obter uma parte da correspondência como um item separado na matriz de resultados.
  • Coloque uma parte do padrão entre parênteses (...)para criar um grupo de captura.
  • Atribua um nome a um grupo de captura colocando ?<name>imediatamente após os parênteses de abertura .(?<name>...)
  • Use $npara fazer referência a um grupo de captura, onde né o número do grupo de captura.

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *