Jump to content
Sign in to follow this  
kingless

[PHP]Full URL Parsing Regex

Recommended Posts

kingless

Boas,

hoje estive no google a procura de uma expressão regular que fizesse o mesmo que a função parse_url(); do php para utilizar em uma classe do meu CMS mas acabei por não encontrar nenhuma expressão que fizesse exactamente aquilo por isso resolvi criar uma expressão regular para fazer aquilo (não foi fácil mas acho que consegui :] ).

<?php
//Full URL Parsing Regex by kingless <blastelf (at) gmail (dot) com> 

$uri = 'http://username:password@www.example.com/path1/path2/file.php?query=1&string=something&this=good#anchor123';

preg_match( '/^(?[a-z]+):\/\/)?(?[\w\-\.]+)?\:*([\w\-\.]+)?\@*)?([\w\.\-]+)*([\/\w]*\/?[\w\.\-]+[^\#\?]+)?(?:\?((?:[^\#].*?)*))?(?:\#?(.*))?$/i', $uri, $match );

print_r( $match );

RESULTADO:

Array
(
    [0] => http://username:password@www.example.com/path1/path2/file.php?query=1&string=something&this=good#anchor123
    [1] => http
    [2] => username
    [3] => password
    [4] => www.example.com
    [5] => /path1/path2/
    [6] => file.php
    [7] => ?query=1&string=something&this=good
    [8] => #anchor123
)

PS: Só não utilizo a função parse_url() porque mostra um E_WARNING quando a URL está mal formada. já agora, se alguém encontrar um bug no regex avise aqui.

Share this post


Link to post
Share on other sites
djthyrax

Em relação ao E_WARNING, o @ não resolve?


Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
Nazgulled

Eu acho que o @ resolvia o problema do E_WARNING, mas não vou afirmar pois não tenho a certeza. No entanto, isso é suposto apenas fazer match aos que estão correctos? É que se eu fizer:

fuck://www.example.com

Funciona, e se calhar não devia... :)

Share this post


Link to post
Share on other sites
kingless

Acham que já não tinha pensado nisso ? :)

Parecendo que não o @ executa muitas operações no "background" para terem uma ideia...

Este código:


for( $x = 0; $x < 1000,; $x++ ) {

      error_reporting(0);

      for( $i = 0; $i < 5; $i++ ) { 
              phpversion();
      }

      error_reporting(E_ALL);
}

É muito mais rápido que este:


for( $x = 0; $x < 1000,; $x++ ) {
      for( $i = 0; $i < 5; $i++ ) { 
              @phpversion();
      }
}

(Se tiverem duvida podem testar ai)

Agora imaginem como é que fica a performance do  CMS se a função parse_url(); for chamada umas 20 vezes com o @...

btw,

Corrigi 4 bugs agora o resultado já se assemelha mais ao do parse_url

EDIT:

fuck://www.example.com

Funciona, e se calhar não devia... :P

Aquilo só faz o parsing das URIs não verifica mas se quiser que isso não funcione é só trocar ([a-z]+) por (http\[s\]?)

Share this post


Link to post
Share on other sites
Nazgulled

@kingless

1) Arranja outro exemplo porque esse do phpverion() provoca um erro fatal e mesmo com @ ou o error_reporting(0), o script termina ai assim que acontecer o primeiro erro. A @ apenas omite o erro, não o vai ignorar...

2) Eu disse "se calhar", porque eu não adivinho o que tu queres fazer, apenas foi uma sugestão. Eu sabia onde tava o erro e resolver isso era básico, foi só mesmo por duas razões, para me meter contigo e porque podia-te ter escapado e ser algo que querias validar, mas pelos vistos não queres.

Share this post


Link to post
Share on other sites
kingless

@kingless

1) Arranja outro exemplo porque esse do phpverion() provoca um erro fatal e mesmo com @ ou o error_reporting(0), o script termina ai assim que acontecer o primeiro erro. A @ apenas omite o erro, não o vai ignorar...

2) Eu disse "se calhar", porque eu não adivinho o que tu queres fazer, apenas foi uma sugestão. Eu sabia onde tava o erro e resolver isso era básico, foi só mesmo por duas razões, para me meter contigo e porque podia-te ter escapado e ser algo que querias validar, mas pelos vistos não queres.

Como o djthyrax disse não é phpverion() mas sim phpversion() :) E para testar aconselho-te o benchmark profiler do PEAR...

Share this post


Link to post
Share on other sites
djthyrax

E para testar aconselho-te o benchmark profiler do PEAR...

Eu normalmente guio-me com o tempo (microtime(true)).

Não peças ajuda por PM! A tua dúvida vai ter menos atenção do que se for postada na secção correcta do fórum!

Share this post


Link to post
Share on other sites
kingless

E para testar aconselho-te o benchmark profiler do PEAR...

Eu normalmente guio-me com o tempo (microtime(true)).

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

Exemplo de resultados de teste do laguna cms:

--------------------------------------------------------------------------------------
Section               Total Ex Time         Netto Ex Time         #Calls    Percentage
--------------------------------------------------------------------------------------
include               0.0119528770447       0.0119528770447       1          12.79%
laguna                0.0270891189575       0.0270891189575       1          28.98%
init                  0.0368528366089       0.0368528366089       1          39.43%
getComponent          0.00298810005188      0.00298810005188      1           3.20%
run                   0.00344586372375      0.00344586372375      1           3.69%
display               0.0105741024017       0.0105741024017       1          11.31%
Global                0.0934681892395       -0.0929028987885      2         100.00%

Share this post


Link to post
Share on other sites
Nazgulled

Desculpa la mas o que tas a dizer não faz sentido nenhum. A arroba, tanto quanto eu sei, é para omitir erros que determinada expressão possa criar, logo, se vais usar a arroba no phpversion(), só por ai, é parvo. o phpversion() existe, logo, não tem lógica nenhuma usar a arroba e/ou o error_reporting, não vão existir erros e não... Se tivesses por exemplo um echo de uma variavel não definida, só provoca um notice e assim, poderia se ver as diferenças de error_reporting() para a arroba, mas o exemplo que deste, não tem sentido nenhum (seja phpverion() ou phpversion()).

Mas pegando no teu exemplo e usando o phpversion(), não notei diferença nenhuma entre os 2... para mim são iguais, não é a diferneça de uns milisegundos que me irá xatear. Acho que tás a dar demasiada importância a pormenores do teu CMS demasiado insignificantes para que alguem esteja minimamente ralado com a forma como o programaste e se poupaste 100ms por teres usado x em vez de y. Acho que devias preocupar mais com o essencial e ter um produto final e estavel em vez de te ralares com esses pormenores. Mas é só o que eu acho.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

Share this post


Link to post
Share on other sites
kingless

Desculpa la mas o que tas a dizer não faz sentido nenhum. A arroba, tanto quanto eu sei, é para omitir erros que determinada expressão possa criar, logo, se vais usar a arroba no phpversion(), só por ai, é parvo. o phpversion() existe, logo, não tem lógica nenhuma usar a arroba e/ou o error_reporting, não vão existir erros e não... Se tivesses por exemplo um echo de uma variavel não definida, só provoca um notice e assim, poderia se ver as diferenças de error_reporting() para a arroba, mas o exemplo que deste, não tem sentido nenhum (seja phpverion() ou phpversion()).

O arroba é para omitir erros claro mas mesmo sem omitir qualquer erro em um loop de 1000 o @ diminiu a perfomance do script em mais ou menos 20 milesimos em relação a um loop de 1000 sem o @ mas com o error_reporting digo isto porque eu testei aqui na minha maquina com o benchmark profiler e mesmo assim não precisas de testar só com o phpversion podes tentar criar um e_warning ou algo assim.

Mas pegando no teu exemplo e usando o phpversion(), não notei diferença nenhuma entre os 2... para mim são iguais, não é a diferença de uns milisegundos que me irá xatear. Acho que tás a dar demasiada importância a pormenores do teu CMS demasiado insignificantes para que alguem esteja minimamente ralado com a forma como o programaste e se poupaste 100ms por teres usado x em vez de y. Acho que devias preocupar mais com o essencial e ter um produto final e estável em vez de te ralares com esses pormenores. Mas é só o que eu acho.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

Eu não estou preocupado com pormenores como o @ eu não utilizei o parse_url por varias razões uma delas foi o @ mas o @ não é a mais importante ao contrario do que possas pensar a razão mais importante para não utilizar o parse_url foi que eu com o preg_match posso fazer o parsing de outras coisas da url como por exemplo do nome do ficheiro que é uma coisa que o parse_url não faz o parsing e posso fazer o parsing como quiser para satisfazer as minhas necessidades.

Quanto a isso do benchmark, podes explicar os resultados? O script é teu, tu é que deves ter uma ideia do que significam, eu olho prai e só vejo numeros, não os sei interpretar.

Na coluna Section são as secções especificas do código que eu selecciono com o profiler para fazer os testes, na coluna Total Ex Time tens o tempo de execução de cada de secção de código que seleccionei, na coluna Netto... não tenho  a certeza mas acho que é quase a mesma coisa que Total Ex Time... na coluna #Calls tens o número de vezes que uma secção foi chamada no CMS e na coluna Percentage tens a percentagem de tempo de execução de cada secção... Não sei se é isso que querias saber :]

Share this post


Link to post
Share on other sites
Nazgulled

Ta bem, mas no post inicial não deixaste claro e o que me pareceu-me foi que querias fazer algo igual com as mesmas funcionalidades mas evitando o E_WARNING e não que querias fazer algo parecido com funcionalidades extra.

Mas anyway, não sei se esses 20ms é por cada iteração no loop ou no total. Se for no total, I rest my case, é parvo usar error_reporting em vez do @ por apenas 20ms. Se for 20ms por cada iteração, no total a diferença era de 1m40s e assim o caso muda de figura. Mas isto era para 5000 iterações (loop de 0 ate 1000 e loop de 1 a 5) e tu disseste que o teu script executava isso uma 20xs, bem, 20ms 20xs, 400ms, não é muito significativo e penso que ninguém iria ficar importado com 400ms. Ate porque não deves chamar essa instrução 20xs seguidas, logo, o tempo de espera sera espaçado e ninguem iria notar o site lento por uns ms a mais.

Bem, ja divaguei de mais sobre o assunto. Faz o que achares melhor, eu continuo a achar a @ melhor que o error_reporting (para o efeito), mas se a ideia é porque o parse_url não faz tudo que tu queres, tudo bem.

Só acho é que ta uma expressão grande de mais, mas também o URL pode ou não ser um bocado complexo, eu não sei se faria melhor e nem se quer vou tentar, obviamente, por isso, fico-me por aqui.

Manda mase uma beta ou alpha disso ca pa fora, que ja andaste nisto aos anos e ainda não vi quase nada :)

Share this post


Link to post
Share on other sites
kingless

Ta bem, mas no post inicial não deixaste claro e o que me pareceu-me foi que querias fazer algo igual com as mesmas funcionalidades mas evitando o E_WARNING e não que querias fazer algo parecido com funcionalidades extra.

A minha intenção era só mostrar  um REGEX  para fazer o parsing completo de uma URL  e talvez uma alternativa para o parse_url que também pode ser utilizada em outras linguagens de programação como por exemplo javascript por isso é que não falei mais sobre o queria fazer. :)

Bem, ja divaguei de mais sobre o assunto. Faz o que achares melhor, eu continuo a achar a @ melhor que o error_reporting (para o efeito), mas se a ideia é porque o parse_url não faz tudo que tu queres, tudo bem.

Só acho é que ta uma expressão grande de mais, mas também o URL pode ou não ser um bocado complexo, eu não sei se faria melhor e nem se quer vou tentar, obviamente, por isso, fico-me por aqui.

Vou ver se faço aqui alguns testes para ver se vale a pena mesmo utilizar o preg_match ou não depois disso eu decido qual é a melhor opção para o que pretendo fazer. :]

Manda mase uma beta ou alpha disso ca pa fora, que ja andaste nisto aos anos e ainda não vi quase nada :)

Se continuar com este ritmo de programação acho que em meados de Setembro já tenho a primeira Alpha  pronta  :P Se não me tivesses motivado no outro dia acho que o CMS não estaria onde esta  :P

Share this post


Link to post
Share on other sites
karva

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

E como é que se usa isso?


Proud LEIC-A@IST student!

Share this post


Link to post
Share on other sites
kingless

Eu também utilizava o microtime para fazer os testes mas agora prefiro o benchmark profiler porque é fácil de usar, tem varias opções e mostra os resultados do teste de uma forma organizada.

E como é que se usa isso?

Podes encontrar alguma documentação sobre o benchmark profiler no site da PEAR -> http://pear.php.net/package/Benchmark/docs/1.2.7/Benchmark/Benchmark_Profiler.html

EDIT:

Não te esqueças que primeiro tens que instalar o benchmark profiler não sei como é que se faz no windows mas no linux eu uso este comando na consola

pear install benchmark

Share this post


Link to post
Share on other sites
MX+

Só para dizer que estou a usar esta função numa biblioteca que vou publicar futuramente aqui no P@P, com o devido cabeçalho "as-in" postaste aqui no forum.

Cumprimentos.

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
Sign in to follow this  

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.