Tworzę aplikację w Google App Engine. Jestem niesamowicie nowy w Pythonie i przez ostatnie 3 dni biję się w głowę z następującym problemem.
Mam klasę do reprezentowania źródła RSS, aw tej klasie mam metodę o nazwie setUrl. Dane wejściowe w tej metodzie to adres URL.
Próbuję użyć modułu re Python do sprawdzenia poprawności RFC 3986 Reg-ex ( http://www.ietf.org/rfc/rfc3986.txt )
Poniżej znajduje się wycięty, który powinien działać?
p = re.compile('^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?')
m = p.match(url)
if m:
self.url = url
return url
python
regex
google-app-engine
Zee Spencer
źródło
źródło
urlparse
nazwa modułu została zmieniona naurllib.parse
w Pythonie 3. Sprawdź docs.python.org/3.7/library/ ...Odpowiedzi:
Łatwym sposobem analizowania (i sprawdzania poprawności) adresów URL jest
urlparse
( py2 , py3 ).Wyrażenie regularne to za dużo pracy.
Nie ma metody „walidacji”, ponieważ prawie wszystko jest prawidłowym adresem URL. Istnieją pewne zasady interpunkcyjne dotyczące dzielenia go. Brak interpunkcji oznacza, że nadal masz prawidłowy adres URL.
Sprawdź dokładnie RFC i zobacz, czy możesz skonstruować „nieprawidłowy” adres URL. Zasady są bardzo elastyczne.
Na przykład
:::::
to prawidłowy adres URL. Ścieżka jest":::::"
. Dość głupia nazwa pliku, ale poprawna nazwa pliku.Ponadto,
/////
jest to prawidłowy adres URL. Netloc („nazwa hosta”) to""
. Ścieżka jest"///"
. Znowu głupia. Również ważne. Ten adres URL normalizuje,"///"
który jest odpowiednikiem.Coś takiego
"bad://///worse/////"
jest całkowicie poprawne. Głupi, ale ważny.Podsumowanie . Przetłumacz to i spójrz na kawałki, aby zobaczyć, czy nie są w jakiś sposób niezadowolone.
Czy chcesz, aby schemat był zawsze „http”? Czy chcesz, aby netloc zawsze miał nazwę „www.somename.somedomain”? Czy chcesz, aby ścieżka wyglądała jak unix? Lub jak okna? Czy chcesz usunąć ciąg zapytania? Albo ją zachować?
To nie są walidacje określone przez RFC. Są to walidacje unikalne dla Twojej aplikacji.
źródło
urlparse
musi być uzupełnione o wyrażenia regularne, aby sprawdzić poprawność netloc (lub innej części) pod kątem określonego standardu.urlparse({})
jeśli dane wejściowe nie są ciągiem znaków, udaje się bez widocznego błęduOto pełne wyrażenie regularne służące do analizowania adresu URL.
Biorąc pod uwagę jego złożoność, myślę, że powinieneś pójść drogą urlparse.
Dla kompletności, oto pseudo-BNF powyższego wyrażenia regularnego (jako dokumentacja):
źródło
Używam tego używanego przez Django i wydaje się, że działa całkiem nieźle:
Zawsze możesz sprawdzić najnowszą wersję tutaj: https://github.com/django/django/blob/master/django/core/validators.py#L74
źródło
Przyznaję, że twoje wyrażenie regularne wydaje mi się całkowicie niezrozumiałe. Zastanawiam się, czy zamiast tego mógłbyś użyć urlparse? Coś jak:
Może być wolniejsze i być może przegapisz warunki, ale wydaje mi się, że jest o wiele łatwiejsze do odczytania i debugowania niż wyrażenie regularne dla adresów URL .
źródło
urlparse
nazwa modułu została zmieniona naurllib.parse
w Pythonie 3. Sprawdź docs.python.org/3.7/library/ ...urlparse
całkiem szczęśliwie przyjmuje nieprawidłowe adresy URL, jest bardziej biblioteką dzielącą ciągi niż jakikolwiek inny walidator. Na przykład:W zależności od sytuacji może to być w porządku.
Jeśli w większości ufasz danym i chcesz tylko sprawdzić, czy protokół to HTTP, to
urlparse
jest idealny.Jeśli chcesz, aby adres URL był faktycznie legalnym adresem URL, użyj śmiesznego wyrażenia regularnego
Jeśli chcesz się upewnić, że to prawdziwy adres internetowy,
źródło
"http://----"
? To całkowicie poprawny adres URL! Po prostu ustaw swoją nazwę hosta na „----” i już możesz jej używać!http://pypi.python.org/pypi/rfc3987 zawiera wyrażenia regularne zapewniające spójność z regułami w RFC 3986 i RFC 3987 (to znaczy nie z regułami specyficznymi dla schematu).
Wyrażenie regularne dla IRI_reference to:
W jednej linii:
źródło
uwaga - Lepl nie jest już obsługiwany ani obsługiwany.
RFC 3696 definiuje „najlepsze praktyki” dotyczące sprawdzania poprawności adresów URL - http://www.faqs.org/rfcs/rfc3696.html
Najnowsza wersja Lepl (biblioteki parsera Pythona) zawiera implementację RFC 3696. Można jej użyć mniej więcej tak:
Chociaż walidatory są zdefiniowane w Lepl, który jest rekurencyjnym parserem zstępującym, są one w większości kompilowane wewnętrznie do wyrażeń regularnych. To łączy w sobie to, co najlepsze z obu światów - (stosunkowo) łatwą do odczytania definicję, którą można porównać z RFC 3696 i wydajną implementacją. Na moim blogu jest post pokazujący, jak to upraszcza parser - http://www.acooke.org/cute/LEPLOptimi0.html
Lepl jest dostępny pod adresem http://www.acooke.org/lepl, a moduł RFC 3696 jest udokumentowany pod adresem http://www.acooke.org/lepl/rfc3696.html
Jest to zupełnie nowe w tej wersji, więc może zawierać błędy. W razie problemów proszę o kontakt, a naprawię je jak najszybciej. Dzięki.
źródło
Obecnie w 90% przypadków, jeśli pracujesz z URL w Pythonie, prawdopodobnie używasz python-requestów. Stąd pytanie - dlaczego nie wykorzystać ponownie weryfikacji adresów URL z żądań?
Cechy:
źródło
Podane wyrażenie regularne powinno pasować do dowolnego adresu URL w postaci http://www.ietf.org/rfc/rfc3986.txt ; i robi, gdy jest testowany w interpreterze Pythona.
Jaki był format adresów URL, z którymi masz problemy podczas analizowania?
źródło
Musiałem to robić wiele razy na przestrzeni lat i zawsze kopiowałem wyrażenie regularne kogoś innego, kto myślał o tym o wiele więcej niż ja chcę o tym myśleć.
Powiedziawszy to, w kodzie formularzy Django znajduje się wyrażenie regularne, które powinno załatwić sprawę:
http://code.djangoproject.com/browser/django/trunk/django/forms/fields.py#L534
źródło
zmodyfikowane wyrażenie regularne sprawdzania poprawności adresu URL django:
źródło: https://github.com/django/django/blob/master/django/core/validators.py#L74
źródło
UWAGA: Tak brzydko wygląda w Twojej przeglądarce, po prostu skopiuj wklej, a formatowanie powinno być dobre
Znalezione na listach mailingowych pythona i używane przez gnome-terminal
źródło: http://mail.python.org/pipermail/python-list/2007-J January / 595436.html
źródło