Linguagem C - Projeto Espião IV
Linguagem C - Projeto Espião III
2796 registros
0 hoje
6 nesta semana
4 neste mês| 88,3% | | Brasil |
| 9,2% | | Portugal |
| 0,8% | | EUA |
| 0,2% | | Espanha |
| 0,1% | | Alemanha |
| Hoje: | 409 |
| Ontem: | 1940 |
| Esta semana: | 2349 |
| Semana passada: | 12942 |
| Este mês: | 2349 |
| Mês passado: | 52379 |
| Total: | 123634 |
|
Sáb 18 Ago 2007 14:29 |
|
Página 1 de 3
Mas antes é bom conhecer o funcionamento básico de um motor regex. O motor regexPodemos ganhar muito tempo se soubermos como funciona o motor regex. Isto evita dores de cabeça ao tentar entender porque determinada expressão regular não devolve o resultado desejado, como também evita trocentas alterações feitas no chute até que a procura funcione como deveria. Então vamos lá. Existem dois tipos de motores: os orientados a texto e os orientados a regex. Os motores orientados a regex são os mais utilizados e oferecem possibilidades mais elaboradas como quantificadores preguiçosos e referências prévias (que são descritas em outros tutoriais). Mas nem por isto o mecanismo de procura orientado a texto é menos importante. Este tipo de motor foi incorporado em ferramentas bastante conhecidas e utilizadas como o banco de dados MySQL, o Procmail e o egrep. É fácil descobrir se um motor é orientado a texto ou a regex. Se você aplicar o regex regex|não regex à string não regex e o resultado for não regex, o motor é orientado a texto; por outro lado, se o resultado for apenas regex, o motor testado é orientado a regex. Motores orientados a regex SEMPRE indicam a primeira ocorrênciaEsta é uma das principais características de motores orientados a regex. Pode parecer uma besteirinha, mas não é: lembre-se que o resultado é sempre a primeira coincidência encontrada, mesmo que exista uma "melhor" ou "mais completa" mais adiante. Quando uma regex é aplicada numa string, o motor começa a pesquisa no primeiro caractere da string fazendo todas as permutações possíveis da expressão regular. Apenas quando todas as possibilidades forem esgotadas e nenhuma combinação for encontrada é que o motor passa para o segundo caracter e assim sucessivamente. Por exemplo, se dar for aplicado a Ciranda, cirandinha, vamos todos cirandar. Vamos dar a meia volta..., o motor vai tentar combinar o primeiro token da regex d com o primeiro caractere da string C - o que obviamente falha. Como não há outras possibilidades de permutação nesta regex, o motor passa para o segundo caractere e compara d com o segundo caractere da string - isto falha novamente. Continuando o processo, o motor finalmente esbarra no sexto caractere da string e encontra o d de "Ciranda" - bingo! É hora de testar os outros tokens da regex: a combina com "Ciranda", mas a coisa pára por aí porque o r do token não combina com a vírgula que vem logo depois de Ciranda. Veja abaixo, onde as não coincidências são mostradas com ":"
Ciranda, cirandinha, vamos todos cirandar. Vamos dar a meia volta...
d ::::: :
da:
O processo continua até que o motor esbarra em "cirandinha", o que também não dá em nada. Finalmente, no trigésimo nono caractere, o motor consegue combinar todos os tokens da regex com os caracteres da string:
Ciranda, cirandinha, vamos todos cirandar. Vamos dar a meia volta...
d ::::: ::::::: :
da::::::: :
d:::::::::::::::::::::::
dar
Como neste ponto ele encontra a primeira combinação válida e como está "ansioso", ele entrega o resultado e pára sem se preocupar se existe uma combinação "melhor" mais para frente. Só para ilustrar como é importante conhecer o funcionamento do motor regex, vamos alterar o exemplo acima para que o motor encontre o "dar" que não faça parte de uma palavra. A primeira idéia é transformar a regex "dar" em " dar". Pois bem, neste caso o primeiro caractere da regex é um espaço e, a cada espaço que encontrar na string, o motor vai ter um trabalho extra testando o segundo token. É claro que vai acabar dando o resultado desejado quando encontrar " dar" em "Vamos dar", mas haja trabalho inútil com todas estas paradas desnecessárias! Se você contar, ao todo serão 5. Por outro lado, se trocarmos a regex por "dar ", o primeiro caracter continua sendo o d e, após 3 paradas, já encontra o que estamos procurando. Só que existe um modo mais elegante de resolver esta questão (veja adiante). Caracteres literaisO exemplo citado mostra uma busca baseada em caracteres literais. O número de caracteres na regex pode ir de um a quantos caracteres você quiser e o princípio da combinação de caracteres é sempre o mesmo. Mas, e se quisermos procurar caracteres especiais? Caracteres especiaisComo não queremos ficar no arroz com feijão, ou seja, fazer apenas procuras com caracteres explícitos, precisamos reservar alguns deles para uso especial (nós não, os autores dos motores regex
Estes caracteres especiais também são conhecidos como metacaracteres. Se quisermos usar qualquer um destes caracteres numa regex de procura, eles precisam ser precedidos pelo caractere de escape. Mas o que é um caractere de escape? Bão, é um sinal que diz para considerar o caractere que vem a seguir literalmente e não como um caractere reservado. O sinal de escape é a contra-barra "\" que manda um recado dizendo que o caractere seguinte é para ser interpretado literalmente, não é para ser interpretado como um caractere com função especial. Com a função do caractere especial \ explicada, como é que podemos anular o caractere de escape para fazer com que o motor o "entenda" como caractere literal? Tá fácil, se nosso regex precisar de uma contra-barra literal, esta precisa ser precedida pelo caractere de escape, ou seja, \\. Mas vamos a um exemplo mais simples. Digamos que o texto pesquisado contenha 1+1=2 e que seja exatamente isto o que estamos procurando. Se nossa regex for 1+1=2, o resultado vai ser um desastre por um motivo muito simples: ela contém o caractere especial +. Como é uma expressão regex válida, ela não vai gerar nenhuma mensagem de erro, só que não vai encontrar a combinação 1+1=2 devido ao significado especial do +. Ainda bem que já conhecemos o caractere de escape que nos fornece uma solução: é só transformar a regex "1+1=2" em "1\+1=2" para que ela funcione como o esperado. Teoricamente, se você quiser garantir que todos os caracteres da sua regex sejam interpretados como caracteres literais, basta preceder cada um deles com uma contra-barra. Só que, neste caso, a perda de tempo é muito grande e, além do mais, acaba dando um monte de problemas. Sabe porque? Aqui está uma lista parcial dos enroscos que podem ocorrer:
e por aí afora. |
|||||
| Última atualização ( Qui, 24.01.2008 19:39 ) |