Estou construindo um aplicativo no Google App Engine. Sou incrivelmente novo em Python e tenho batido minha cabeça contra o seguinte problema nos últimos 3 dias.
Eu tenho uma classe para representar um RSS Feed e nesta classe tenho um método chamado setUrl. A entrada para este método é um URL.
Estou tentando usar o módulo re python para validar fora do RFC 3986 Reg-ex ( http://www.ietf.org/rfc/rfc3986.txt )
Abaixo está um recorte que deve funcionar?
p = re.compile('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?')
m = p.match(url)
if m:
self.url = url
return url
python
regex
google-app-engine
Zee Spencer
fonte
fonte
urlparse
módulo foi renomeado paraurllib.parse
em Python 3. Verifique docs.python.org/3.7/library/…Respostas:
Uma maneira fácil de analisar (e validar) URLs é o módulo
urlparse
( py2 , py3 ).Uma regex é muito trabalhosa.
Não existe um método de "validação" porque quase tudo é um URL válido. Existem algumas regras de pontuação para dividir. Sem pontuação, você ainda tem um URL válido.
Verifique o RFC cuidadosamente e veja se você pode construir um URL "inválido". As regras são muito flexíveis.
Por exemplo,
:::::
é um URL válido. O caminho é":::::"
. Um nome de arquivo bastante estúpido, mas um nome de arquivo válido.Além disso,
/////
é um URL válido. O netloc ("hostname") é""
. O caminho é"///"
. De novo, estúpido. Também válido. Este URL normaliza para o"///"
que é equivalente.Algo assim
"bad://///worse/////"
é perfeitamente válido. Idiota, mas válido.Linha de fundo . Analise-o e observe as peças para ver se estão desagradando de alguma forma.
Você quer que o esquema seja sempre "http"? Você deseja que o netloc seja sempre "www.somename.somedomain"? Você quer que o caminho seja semelhante ao Unix? Ou como o Windows? Você deseja remover a string de consulta? Ou preservá-lo?
Estas não são validações especificadas por RFC. Essas são validações exclusivas para seu aplicativo.
fonte
urlparse
precisa ser aumentado com regexes para validar um netloc (ou outra parte) em relação a um padrão específico.urlparse({})
quando a entrada não é nem mesmo uma string é bem-sucedida sem um erro visívelAqui está o regexp completo para analisar um URL.
Dada sua complexidade, acho que você deve seguir o caminho mais direto.
Para completar, aqui está o pseudo-BNF do regex acima (como uma documentação):
fonte
Estou usando o usado pelo Django e parece funcionar muito bem:
Você sempre pode verificar a versão mais recente aqui: https://github.com/django/django/blob/master/django/core/validators.py#L74
fonte
Eu admito, acho sua expressão regular totalmente incompreensível. Eu me pergunto se você poderia usar o urlparse em vez disso. Algo como:
Pode ser mais lento e talvez você perca as condições, mas parece (para mim) muito mais fácil de ler e depurar do que uma expressão regular para URLs .
fonte
urlparse
módulo foi renomeado paraurllib.parse
em Python 3. Verifique docs.python.org/3.7/library/…urlparse
felizmente aceita URLs inválidos, é mais uma biblioteca de divisão de string de string do que qualquer tipo de validador. Por exemplo:Dependendo da situação, isso pode ser bom ..
Se você confia principalmente nos dados e deseja apenas verificar se o protocolo é HTTP, então
urlparse
é perfeito.Se você quiser fazer com que o URL seja, na verdade, um URL legal, use a expressão regular ridícula
Se você quiser ter certeza de que é um endereço da web real,
fonte
"http://----"
?? É um url perfeitamente válido! Basta definir o seu hostname para "----" e você já pode usá-lo!http://pypi.python.org/pypi/rfc3987 fornece expressões regulares para consistência com as regras em RFC 3986 e RFC 3987 (ou seja, não com regras específicas de esquema).
Uma regexp para IRI_reference é:
Em uma linha:
fonte
observação - Lepl não é mais mantido ou suportado.
RFC 3696 define "práticas recomendadas" para validação de URL - http://www.faqs.org/rfcs/rfc3696.html
A versão mais recente do Lepl (uma biblioteca do analisador Python) inclui uma implementação do RFC 3696. Você o usaria da seguinte forma:
Embora os validadores sejam definidos em Lepl, que é um analisador descendente recursivo, eles são amplamente compilados internamente em expressões regulares. Isso combina o melhor dos dois mundos - uma definição (relativamente) fácil de ler que pode ser verificada no RFC 3696 e uma implementação eficiente. Há uma postagem em meu blog mostrando como isso simplifica o analisador - http://www.acooke.org/cute/LEPLOptimi0.html
Lepl está disponível em http://www.acooke.org/lepl e o módulo RFC 3696 está documentado em http://www.acooke.org/lepl/rfc3696.html
Isso é completamente novo nesta versão, então pode conter bugs. Entre em contato comigo se tiver algum problema e eu irei corrigi-lo o mais rápido possível. Obrigado.
fonte
Hoje em dia, em 90% dos casos, se você trabalhar com URL em Python, provavelmente usará solicitações de python. Daí a questão aqui - por que não reutilizar a validação de URL de solicitações?
Recursos:
fonte
O regex fornecido deve corresponder a qualquer url no formato http://www.ietf.org/rfc/rfc3986.txt ; e faz quando testado no interpretador python.
Qual é o formato dos URLs que você está tendo problemas para analisar?
fonte
Eu precisei fazer isso muitas vezes ao longo dos anos e sempre acabo copiando a expressão regular de outra pessoa que pensou sobre isso muito mais do que eu gostaria .
Dito isso, há uma regex no código de formulários do Django que deve resolver o problema:
http://code.djangoproject.com/browser/django/trunk/django/forms/fields.py#L534
fonte
regex de validação de url django modificado:
fonte: https://github.com/django/django/blob/master/django/core/validators.py#L74
fonte
NOTA: Por mais feio que pareça no seu navegador, basta copiar e colar e a formatação deve ser boa
Encontrado nas listas de discussão do python e usado para o gnome-terminal
fonte: http://mail.python.org/pipermail/python-list/2007-January/595436.html
fonte