43
Regex a.k.a. RegExp

Regex

Embed Size (px)

DESCRIPTION

Uma introdução a expressões regulares e bibliotecas regex.

Citation preview

Page 1: Regex

Regexa.k.a. RegExp

Page 2: Regex

Verifica se número é primo

^1?$|^(11+?)\1+$

Page 3: Regex

Verifica se número é primo

Isso não é uma expressão regular

^1?$|^(11+?)\1+$

Page 4: Regex

Verifica se número é primo

Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas

regex)

^1?$|^(11+?)\1+$

Page 5: Regex

Verifica se número é primo

Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas

regex)É difícil de entender

^1?$|^(11+?)\1+$

Page 6: Regex

Verifica se número é primo

Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas

regex)É difícil de entenderÉ fácil de errar

^1?$|^(11+?)\1+$

Page 7: Regex

Verifica se número é primo

Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas

regex)É difícil de entenderÉ fácil de errarÉ extremamente compacta

^1?$|^(11+?)\1+$

Page 8: Regex

Verifica se número é primo

Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas

regex)É difícil de entenderÉ fácil de errarÉ extremamente compactaNa verdade, checa se número não é primo

^1?$|^(11+?)\1+$

Page 9: Regex

HistóricoConceito matemático introduzido na década de

50SNOBOL implementou pattern matching, mas

não expressões regularesKen Thompson introduzir expressões regulares

no editor QED, depois ed (Unix), e finalmente grep (abreviação do comando g/re/p do ed)

Padronizado pelo POSIXRepadronizado pelo Perl e Tcl (baseado em

biblioteca de Henry Spencer)Biblioteca PCRE (Philip Hazel)

Page 10: Regex

Para que servem Regex?Verificar se um determinado padrão ocorre em

um textoVerificar se um determinado padrão não ocorre

em um textoLocalizar as ocorrências de um padrãoObter as ocorrências de um padrãoObter partes das ocorrências de um padrãoSubstituir ocorrências de um padrão por outro

texto, possivelmente usando partes da ocorrênciaDividir texto de acordo com um padrão

Page 11: Regex

ExemplosAcha linhas com configurações:

grep "^ *[^# ]" php.iniAcha linhas que não estejam em branco:

grep –v "^$" .profile Índice de todas palavras em um texto:

[w.start() for w in re.finditer(r'\b\w', text)]Todas palavras de um texto:

@words = $text =~ /\w+/Dia, mês e ano de uma data:

($d, $m, $a) = text =~ /(\d\d)/(\d\d)/(\d{4})/Remove espaços do fim da linha:

sed -p'' -e 's/ *$//‘Divide linha em palavras e símbolos

text split """\b\s*|\s*\b"""

Page 12: Regex

Expressões RegularesDescrevem Linguagens RegularesMesmo poder expressivo de Gramáticas

RegularesMesmas linguagens aceitas por Autômatos

Finitos DeterminísticosLivres de ContextoExemplo de linguagem não regular:

Número de b depende do número de a: anbn

Page 13: Regex

Autômatos Finitos Determinísticos

0 1

\n

[^\n]

\n

[^\n]

Texto termina em \n?

Regex:.*\n$

Page 14: Regex

Dois switches e um loop// Texto termina em \n?int state = 0;while(ch = getc()) { switch(state) { case 0: switch(ch) { case '\n': state = 1; break; default : break; } case 1: switch(ch) { case '\n': break; default : state = 0; break; } }}return state == 1;

Page 15: Regex

Estrutura de uma RegexComposta de:

Um caracter (literal)Ou nada (string vazia)Ou uma composição de uma ou duas outras

regex

Page 16: Regex

Operações de ComposiçãoDa maior precedência para a menor:

Repetição (kleene star): r*Concatenação: r1 r2

Alternativa: r1 | r2

Todas expressões regulares podem ser compostas a partir desses elementos

Muitas regex não podem ser compostas só com esses elementos

Page 17: Regex

Tipos de RegexPOSIX Basic Regex (grep)POSIX Extended Regex (grep –E)Preg (Perl regex)PCRE (Perl Compatible(*) Regular

Expression)(*) Só que não

Etc... (cada biblioteca tem suas particularidades)

Page 18: Regex

Regex Compilado vs JITCompilar um regex transforma a string

representando o regex em uma estrutura de dados otimizada para seu usoDisponível com Java, Perl, Python, Ruby

Regex Just In Time recompilam a expressão todas as vezes, para diminuir a cerimônia de seu usoDisponível com Java(*), Perl, PHP, Python, Ruby

(*) Somente para alguns usos

Page 19: Regex

Outras operações de ComposiçãoQualquer caracter: .Qualquer um de um conjunto: [r1r2-r3]

Qualquer um não em um conjunto: [^r1r2]Classes de caracteres: [[:alpha:]], \w,Negação de classes: [^[:alpha:]], \WClasses POSIX: \p{Upper}, \P{InGreek}Zero ou um: r?Um ou mais: r+Entre n e m repetições: r{n, m}

Page 20: Regex

Classes úteis[:alnum:]\w – inclui sublinhado (não palavras como \W)[:alpha:][:blank:][:cntrl:][:digit] ou \d (não dígito como \D)[:graph:][:lower:][:print:][:punct:][:space:] ou \s (não espaço como \S)[:upper:][:xdigit:]

Page 21: Regex

GreedinessAs expressões r* e r+ retornam a maior

quantidade possível de caracteres que satisfaçam a expressão

Elas são greedy – gananciosasAlgumas bibliotecas suportam relutância:

r*? e r+?Elas retornam a menor quantidade

possível de caracteres que satisfaçam a expressão

Em alguns casos, a performance das repetições relutantes é muito superior

Page 22: Regex

Relembrando PrecedênciaLembrando a precedência: repetição,

concatenação e alternativaTextos que satisfazem a expressão ab*|cd:

aababbcd

Os textos abab e acd não satisfazem a expressão

Page 23: Regex

AgrupamentoPOSIX Basic Regular Expression: \( e \)Todo o resto: ( e )Grupos também capturam o conteúdo, e

podem ser extraídos separadamente ou usados na substituição

Sem captura(*): (?:r)(*) as partes de uma ocorrência

correspondentes a expressões dentro de parênteses são retornadas como grupos ou subgrupos

Page 24: Regex

ContextoEu falei que expressões regulares são linguagens

sem contextoMas esses “contextos” são válidos, pois podem ser

representados como estadosÂncoras:

Início do texto ou de uma linha: ^Fim do texto ou de uma linha: $

Borda de palavras: \b ou \< e \> (POSIX BRE)Look-ahead: (?=r)Look-behind: (?<=r)Negações: (?!r) e (?<!r)

Page 25: Regex

Contexto de verdadeNão suportados por expressões regularesSuportados por quase todas bibliotecas regexPodem levar a tempos exponenciaisBack references: \n (para n de 1 a 9)

Page 26: Regex

Alterações de ComportamentoFormato:

Ativa/Desativa: (?idmsux-idmsux)Somente para o subgrupo: (?idmsux-idmsux:r)

Flags:Case insensitive: iUnix new lines: dMultiline: m“.” pega new lines: sUnicode-aware: uComentários: x

Page 27: Regex

Escaping (citando caracteres)PCRE:

\ antes de símbolos cita o símbolo\ antes de letras tem tem significado especial

POSIX Basic RE: uma zona – consulte o manual

Citando um grupo de caracters:\Qgrupo de caracteres\E

Page 28: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 29: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 30: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 31: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 32: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 33: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 34: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 35: Regex

Revisitando Números Primos^1?$|^(11+)\1+$

CaracteresÂncoras

Alternativas

Agrupamento Back ReferenceRepetições

Concatenação

Page 36: Regex

Explicando Números Primos(?x) # Dado uma sequência de dígitos 1, aceita se o # tamanho da sequência não for um número primo

# Primeiro caso, números menores que 2^ # Início da string1? # 0 ou 1 ocorrênicas do dígito 1$ # Fim da String

| # Segundo caso, números maiores ou igual a 2 # Verifica se a string pode ser reduzida a # XX...X, onde X é uma string de tamanho fixo # com dois ou mais dígitos 1

^ # Início da string( # Início do primeiro subgrupo -- o “X” da questão11+? # Sequência de dois ou mais dígitos 1 # A sequência acima é relutante por questões de performance) # Fim da sequência\1+ # Uma ou mais (novas) ocorrências do subgrupo 1$ # Fim da string

Page 37: Regex

E-mail regex

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

Page 38: Regex

XML Regex

Page 39: Regex

Moral da HistóriaCoisas que não são regex as vezes podem ser

resolvidas com regexCoisas que são regex as vezes não valem a

pena serem resolvidas com regexAlgumas coisas não são regex e não são

resolvidas com regexResolver com código expressões regulares

simples é muito mais complicado do que as pessoas assumem

Não usem regex com xml!

Page 40: Regex

Criando e Testando RegexRegexBuddy (produto comercial): o melhor

de todosDFA/Regex:

http://osteele.com/tools/reanimator/.Net:

http://www.nregex.com/nregex/default.aspxJava: http://www.myregexp.com/JavaScript: http://www.regexpal.com/Perl: http://www.regextester.com/ (tb PHP,

POSIX)PHP: http://regex.larsolavtorvik.com/ (tb

Javascript)Python: http://www.pythonregex.com/Ruby: http://www.rubular.com/

Page 41: Regex

Exemplo Javaimport java.util.regex.Pattern;import java.util.regex.Matcher;

Pattern pattern = Pattern.compile("pattern");Matcher matcher = pattern.matches("text");

Matcher.find(); matcher.matches();

matcher.replaceFirst("replacement"); matcher.replaceAll(Matcher.quoteReplacement("replacement"));

MatchResult matchResult = matcher.toMatchResult();

text.split("pattern");

Page 42: Regex

Exemplo Python# Compila & Buscaprog = re.compile(r"pattern")result = prog.match("text")# Atalhoresult = re.match(r"pattern", "text")

re.search("text") re.findall("text"); re.finditer("text")

re.sub("replacement", "text")

re.split("text")

Page 43: Regex

The End