Expressões Regulares: Como a correspondência de grupos é útil?

6

Eu decidi aprender algumas noções básicas de expressões regulares. Estou usando as lições do Regex One on-line e fiquei preso na lession 11 por um tempo, mas acho que consegui agora.

Esta foi a tarefa.

"Escreva uma expressão regular que corresponda apenas aos nomes dos arquivos (sem incluir a extensão) dos arquivos PDF abaixo."

task            text                     capture
capture text    file_a_record_file.pdf   file_a_record_file
capture text    file_yesterday.pdf       file_yesterday
skip text       testfile_fake.pdf.tmp

Existe um campo de entrada onde você digita o padrão para completar a tarefa. Depois de algumas tentativas e erros, foi isso que eu criei.

^(file_a_record_file)\.pdf$

Isso corresponderá ao nome do arquivo file_a_record_file.pdf , mas apenas "capturará" o arquivo_a_record_file . Qual é a diferença? ... entre combinar e "capturar"? E como isso é útil? Como é essa "correspondência de grupo"?

Agora isso funciona para o primeiro arquivo, mas não para o segundo arquivo. A tarefa diz que preciso criar um padrão que corresponda e capture o nome do arquivo de ambos os arquivos, excluindo a extensão. Então é isso que eu fiz em seguida.

^(file_.*)\.pdf$

Como os dois nomes de arquivo começam com arquivo _ , achei que seria uma boa ideia compará-lo a ele e, em seguida, dizer a ele para corresponder a qualquer caractere seguinte e sair do grupo com parênteses (o "group" é o que está dentro dos parênteses, certo?) e escape do ponto com uma barra invertida e termine com a extensão do nome do arquivo.

Isso pode ser descrito de uma maneira mais rigorosa? As soluções corretas não são dadas no site. Então não tenho nada para checar minhas respostas. É uma pena porque acho que esta é uma boa introdução às expressões regulares. Os exemplos dados para cada lição às vezes são difíceis de entender.

E mais uma vez, como isso é útil? Ele menciona algo sobre linha de comando, eu acho que ele quer dizer que ele pode ser usado para reutilizar comandos ou algo assim ... bem, eu realmente não entendo o que ele está dizendo.

Imagine that we have a command line tool that copies each file in a directory up to a server only if it doesn't exist there already, and prints each filename as a result. Now if I want to do another task on each of those filenames, then I will not only need a regular expression that will match the filename, but also some way to extract that information.

Extraindo informação? Do que ele está falando? Alguém pode me dizer como isso é útil e me dar um exemplo do mundo real?

    
por Samir 20.06.2013 / 17:57

2 respostas

8

Na lição que você vinculou, você é solicitado a escrever um regex que capture o nome do arquivo desses dois

file_a_record_file.pdf
file_yesterday.pdf

e pula

testfile_fake.pdf.tmp

O regex mais simples para fazer isso é

(.*)\.pdf$

Isso significa que corresponde a tudo que termina em .pdf , mas captura apenas o nome do arquivo.

Então, por que capturar é útil? Isso depende do programa com o qual você está usando esses regexes. A captura de padrões permite salvar o que você capturou como variável. Por exemplo, usando Perl, o primeiro padrão capturado é $1 , o segundo $2 etc:

echo "Hello world" | perl -ne '/(.+) (.+)/; print "$2 $1\n"'

Isso imprimirá "world Hello" porque o primeiro parêntesis capturou Hello e o segundo capturou world , mas estamos imprimindo $2 $1 para que as duas correspondências sejam invertidas.

Outras implementações regex permitem que você se refira aos padrões capturados usando , etc. Por exemplo, GNU sed :

echo "Hello world" | sed 's/\(.*\) \(.*\)/ /'

Assim, em geral, a captura de padrões é útil quando você precisa se referir a esses padrões mais tarde. Isso é conhecido como referenciamento e é brevemente explicado um pouco mais tarde nos tutoriais que você está fazendo.

    
por 20.06.2013 / 18:09
1

Mais curto:

(.*)\.pdf$



Por que capturar / agrupar:

Quando você está transmitindo o regex para um programa ou usando-o em seu programa, é necessário armazenar as correspondências , use o agrupamento.

Tomando o exemplo regex acima, o programa verifica se o regex combina, se isso acontecer, você pode simplesmente pegar a frase que você incluiu com ( )

Demo:

String stringToCheck = "example.pdf";           // Example string for testing
Pattern p = Pattern.compile("(.*)\.pdf$");      // Matching regex
Matcher m = r.matcher(stringToCheck);           // Java's own component to 'match' the string, proccessing is here
if (m.matches()) {                              // Check if the regex has matched
                                                // What? How to reterive the filename?
                                                // That's why we grouped our filename in the regex
    String filename = m.group(1);               // Reterive the first grouped part
    System.out.println(filename);               // Java's own way to print string, this is printing filename
}                                               // ??? PROFIT
    
por 13.07.2015 / 03:51

Tags