View
1.206
Download
6
Category
Preview:
DESCRIPTION
Uma introdução a expressões regulares e bibliotecas regex.
Citation preview
Regexa.k.a. RegExp
Verifica se número é primo
^1?$|^(11+?)\1+$
Verifica se número é primo
Isso não é uma expressão regular
^1?$|^(11+?)\1+$
Verifica se número é primo
Isso não é uma expressão regular(mas é aceito por quase todas bibliotecas
regex)
^1?$|^(11+?)\1+$
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+$
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+$
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+$
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+$
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)
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
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"""
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
Autômatos Finitos Determinísticos
0 1
\n
[^\n]
\n
[^\n]
Texto termina em \n?
Regex:.*\n$
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;
Estrutura de uma RegexComposta de:
Um caracter (literal)Ou nada (string vazia)Ou uma composição de uma ou duas outras
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
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)
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
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}
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:]
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
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
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
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)
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)
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
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
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
Revisitando Números Primos^1?$|^(11+)\1+$
CaracteresÂncoras
Alternativas
Agrupamento Back ReferenceRepetições
Concatenação
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
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])+)\])
XML 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!
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/
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");
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")
The End