Jump to content
Manimal

Expressões Regulares - RegEx - Parte 2

Recommended Posts

Olá pessoal.
Dando continuidade ao papo sobre Expressões Regulares, como já apresentamos a idéia e como funciona, vamos mostrar os principais códigos que podem ser utilizados nas Expressões Regulares (RegEx).
Como visto, as RegEx trabalham em cima de padrões de pesquisa portanto é muito importante que saibamos montar as expressões conhecendo os códigos e a diferença entre estes e as strings convencionais.
As vezes é muito confuso. Volta e meia eu também me perco e me atrapalho com os códigos. Principalmente o . (ponto). Força do hábito... Mas vamos lá:
Ficaremos apenas com os códigos mais comuns! Existem vários outros. Na internet tem vários tutoriais e manuais explicando cada um deles!
Separamos os códigos por categoria (organização apenas) sendo:
Metas
  • \w = qualquer letra do alfabeto, mais especificamente de a até o z, maiúsculas ou minúsculas e os dígitos de 0 a 9
  • \d = somente os dígitos de 0 a 9
  • \s = espaço, mais como terminator pois além do espaço engloba também o CR = Chr(13), o LF = Chr(10), TAB = Chr(9) e FormFeed = Chr(12)
  • . (ponto) = qualquer caracter. Sério qualquer mesmo! letras, dígitos, pontuação, caracteres especiais... É O curinga da RegEx!
  • [] = o que estiver entre os colchetes é apenas 1 (uma) letra, mas pode ser qualquer das letras. Ex: [abc] = pode ser a letra A ou B ou C. Não é o conjunto ABC. São letras individuais!
Neste caso, usar os códigos tem uma enorme diferenciação entre código em MAIÚSCULAS ou MINÚSCULAS
  • \W = qualquer coisa que NÃO seja letras de a até z ou dígitos, Literalmente negação do \w
  • \D = qualquer coisa que NÃO seja dígitos de 0 a 9
  • \S = qualquer coisa que NÃO seja espaços ou terminadores

Quantificadores

  • ? = 0 (zero) ou 1 (uma) ocorrência
  • * = 0 (zero) ou mais ocorrências
  • + = 1 (uma) ou mais ocorrências
  • {} = apenas 1 (um) número entre chaves representa a quantidade EXATA de ocorrências. Ex: {3} = 3 vezes, {2} = 2 vezes, {145} = 145 vezes
  • {} = para intervalos, informar o mínimo e o máximo. Ex: {1,3} de 1 a 3 vezes, {6,8} de 6 a 8 vezes, {3,} no mínimo 3 sem máximo
Âncoras
  • ^ = início da linha
  • $ = final da linha
Grupos
  • () = o que fica entre os parênteses pode ser capturado para retornar como elementos individuais
  • Vamos falar dos grupos mais tarde, quando precisarmos recuperar informações.
Os códigos acima podem combinados e misturados à vontade para criar os padrões que precisamos. Utilizamos os códigos acima em conjunto com as strings literais que procuramos.
Ou seja, para procurarmos 3 nros, podemos usar:
\d\d\d
Como alternativa para não repetir os códigos também podemos usar
\d{3}
Qual está correta? Ambas. Na verdade são a mesma coisa. Não faz diferença. É apenas uma questão de legibilidade ou costume.
Lembrando sempre que enquanto pesquisa, nosso maior objetivo é encontrar uma substring dentro de uma string maior, portanto a maioria das vezes começamos sempre com os literais (string normal) e vamos incrementando. Vou utilizar como exemplo nomes de seriados de TV, que vem basicamente assim:
  • The.Blacklist.S03E13.HDTV.x264-FUM
  • Criminal.Minds.S04E02.The.Angel.Maker.DVDRip.XviD-SAiNTS
  • Game.of.Thrones.S06E08.HDTV.x264-KILLERS[eztv]
  • Eureka.S03E06.HDTV.XviD-aAF
  • The.IT.Crowd.S03E01.WS.PDTV.XviD-RiVER
Podemos observar que o identificador da temporada e do episódio estão inseridos no nome do arquivo.
Então para fins de teste, podemos fazer uma RegEx para verificar se existe a temporada e o nro do episódio em cada um dos nomes.
Começamos com a temporada e depois evoluímos para a temporada mais o episódio
Observando os nomes, partimos do princípio que toda temporada começa com um "S" seguido de dois nros.
Então a expressão ficaria inicialmente:
S\d\d
Como alternativa poderia ser S\d{2}. Atenção que o "S" é maiúsculo! Se houver alguma nome com "s" minúsculo não bate com a expressão!
Seguindo o mesmo princípio, então o nro do episódio viria na sequência logo após a letra E seguido de mais 2 dígitos. Daí nossa expressão se tornaria:
S\d\dE\d\d
Assim estou dizendo à função para procurar um padrão (S maiusc, dígito, dígito, E maiusc, dígito, dígito) e não apenas um literal!
Assim aplicando a expressão na função ficaria:
If StringRegExp($Nome_Episodio, "S\d\dE\d\d") Then MsgBox(0, "Info", "Achou")
Podemos ampliar a expressão levando em conta que as letras S ou E podem ser ambas minúsculas ou combinação.
Para isso utilizaremos os colchetes = [] para especificar o que queremos. A expressão ficaria:
[Ss]\d\d[Ee]\d\d
Ou seja, procure um "S" maiusc OU um "S" minusc, seguido de 2 dígitos, seguido de um "E" maiusc OU "E" minusc, seguido de 2 dígitos também.
Nossa que confusão! Não é difícil. É questão de treino e prática. Mas que pode ficar bem complicado rapidinho! Outro detalhe é que às vezes, vale a pena dividir o RegEx em várias expressões menores que fica mais fácil de administrar do que fazer uma RegEx GIGANTE que contenha todas as opções possíveis.
Dica: É difícil montar as expressões e ver o que está acontecendo.
Eu uso o site https://regex101.com/#pcre direto. Já testei vários sites e/ou programas e este foi o que mais gostei!
Porque dá para montar a expressão no primeiro quadro e no quadro de baixo colocar os exemplos do que deve ser procurado.
Ou seja, na primeira linha eu coloco S\d\dE\d\d e no quadro de baixo eu copio e colo os nomes das séria acima.
Assim eu consigo montar as expressões e ver se funcionam até porque do lado direito vai decifrando as expressões ;)
Atenção: se vc usar várias linhas de exemplo (como neste caso), no 2o quadro ao lado da expressão, coloque gm (letra G e letra M) - depois eu explico como fazer isso em AutoIt ou porquê.
Na terceira parte, vamos montar algumas expressões um pouquinho mais complicadas, aprender a trabalhar com grupos e como recuperar informações da função StringRegExp.
  • Like 3

Share this post


Link to post
Share on other sites

@Manimal

 

Como eu consigo pegar só uma parte dessa string abaixo usando StringRegExp?

 

$string = 'C:\Users\Fábio\Desktop\02.Kyoto [Feat. Sirah].mp3'

 

Quero pegar somente o nome : 02.Kyoto [Feat. Sirah]

 

Que fica depois da última barra (\) e antes do último ponto final (.)

 

Share this post


Link to post
Share on other sites

Boa noite Fábio.

 

Uma forma bem simples de recuperar a parte que vc deseja, assumindo que todas as músicas estão na pasta Desktop, seria:

#include <StringConstants.au3>
$string = 'C:\Users\Fábio\Desktop\02.Kyoto [Feat. Sirah].mp3'
If StringRegExp($string, '\\Desktop\\(.+)\.mp3') Then $Nome = StringRegExp($string, '\\Desktop\\(.+)\.mp3', $STR_REGEXPARRAYMATCH)[0]
ConsoleWrite($Nome & @CRLF)
 

Share this post


Link to post
Share on other sites

@Manimal primeiramente muito Obrigado pela resposta, funcionou direitinho.

 

Agora tenho outra dúvida, pois nem sempre as músicas estarão na pasta Desktop, portanto como pegar oque está entre as duas barras finais.

 

Ex: $string = 'C:\Fábio\Músicas\Capital Inicial - A*****stico MTV\07.Eu vou Estar.mp3'

 

Se não for incomodo ainda não assimilei essa sintaxe dessa função, como seria para pegar o nome da pasta: Capital Inicial - A*****stico MTV

Share this post


Link to post
Share on other sites

@Fábio iGames

 

Blz? Desculpe o atraso.

 

Olha, não tem como pegar exatamente a última pasta sem montar um RegEx muito complexo.

Na verdade tem, mas entra numa seara de como funciona o mecanismo interno da função RegEx, mas pode ser feito da seguinte maneira:

#include <StringConstants.au3>

$String = "C:\Fábio\Músicas\Capital Inicial - Acústico MTV\07.Eu vou Estar.mp3"
$Pasta = StringRegExp($String, '(?:\\([^<>:"/|?*]+?)(?=\\))+', $STR_REGEXPARRAYMATCH)[0]
ConsoleWrite($Pasta & @CRLF)
 

Segue outro exemplo de como recuperar todas as pastas do caminho:

#include <Array.au3>
#include <StringConstants.au3>

Local $String = "C:\Fábio\Músicas\Capital Inicial - Acústico MTV\07.Eu vou Estar.mp3"
Local $Pastas = StringRegExp($String, '\\([^<>:"/|?*]+?)(?=\\)', $STR_REGEXPARRAYGLOBALMATCH)
_ArrayDisplay($Pastas)
 

No exemplo acima, o array $Pastas contém cada uma das pastas que compõe o nome do arquivo ficando assim:

$Pastas[0] = "Fábio"

$Pastas[1] = "Músicas"

$Pastas[2] = "Capital Inicial - A*****stico MTV"

 

Quanto à sintaxe, é complicada mesmo! Eu também às vezes tenho que parar e olhar "4 veiz" até resolver :huh:

 

Mas quanto mais vc usa, mais vc se acostuma.

 

Pretendo agora na terceira parte do Tutorial, explicar melhor os grupos e substituições.

Edited by Manimal

Share this post


Link to post
Share on other sites

@Manimal por hora está bom D+ a sua ajuda, os exemplos funcionam perfeitamente.

 

Tem coisas complexas nessa função, depois vou estudar mais afundo.

 

MUITO OBRIGADO. :like_icon:

  • Like 1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


×