Próbuję dopasować <input>
„ukryte” pola typu, używając tego wzorca:
/<input type="hidden" name="([^"]*?)" value="([^"]*?)" />/
To są przykładowe dane formularza:
<input type="hidden" name="SaveRequired" value="False" /><input type="hidden" name="__VIEWSTATE1" value="1H4sIAAtzrkX7QfL5VEGj6nGi+nP" /><input type="hidden" name="__VIEWSTATE2" value="0351118MK" /><input type="hidden" name="__VIEWSTATE3" value="ZVVV91yjY" /><input type="hidden" name="__VIEWSTATE0" value="3" /><input type="hidden" name="__VIEWSTATE" value="" /><input type="hidden" name="__VIEWSTATE" value="" />
Ale nie jestem pewien, że type
, name
, oraz value
atrybuty zawsze będą pojawiać się w tej samej kolejności. Jeśli type
atrybut jest ostatni, dopasowanie nie powiedzie się, ponieważ według mojego wzoru jest na początku.
Pytanie:
Jak mogę zmienić swój wzór, aby pasował bez względu na pozycje atrybutów w <input>
znaczniku?
PS: Przy okazji używam opartego na Adobe Air RegEx Desktop Tool do testowania wyrażeń regularnych.
Odpowiedzi:
W przeciwieństwie do wszystkich odpowiedzi tutaj, to, co próbujesz zrobić, to doskonałe rozwiązanie. Wynika to z faktu, że NIE próbujesz dopasować zrównoważonych tagów - NIE byłoby to możliwe z regex! Ale dopasowujesz tylko to, co jest w jednym tagu, i to jest idealnie regularne.
Oto problem. Nie możesz tego zrobić za pomocą tylko jednego wyrażenia regularnego ... musisz zrobić jedno dopasowanie, aby przechwycić
<input>
tag, a następnie wykonać dalsze przetwarzanie. Zauważ, że zadziała to tylko wtedy, gdy żadna z wartości atrybutów nie zawiera>
znaku, więc nie jest idealna, ale powinna wystarczyć dla rozsądnych danych wejściowych.Oto trochę Perl (pseudo) kod, który pokaże ci, co mam na myśli:
Podstawową zasadą jest tutaj: nie próbuj robić zbyt wiele za pomocą jednego wyrażenia regularnego. Jak zauważyłeś, wyrażenia regularne wymuszają pewną ilość zamówienia. Zamiast tego musisz najpierw dopasować KONTEKST tego, co próbujesz wyodrębnić, a następnie przesłać żądane dane.
EDYCJA: Zgadzam się jednak, że generalnie użycie parsera HTML jest prawdopodobnie łatwiejsze i lepsze i naprawdę powinieneś rozważyć przeprojektowanie kodu lub ponowne zbadanie celów. :-) Ale musiałem opublikować tę odpowiedź jako przeciwstawienie się szarpanemu kolanom reakcji, że parsowanie dowolnego podzbioru HTML jest niemożliwe: zarówno HTML, jak i XML są nieregularne, jeśli wziąć pod uwagę całą specyfikację, ale specyfikacja tagu jest przyzwoicie regularna , na pewno w mocy PCRE.
źródło
O tak, możesz użyć Regexes do parsowania HTML!
W przypadku zadania, które próbujesz, wyrażenia regularne są w porządku!
Prawdą jest, że większość ludzi nie docenia trudności w przetwarzaniu HTML za pomocą wyrażeń regularnych i dlatego robi to słabo.
Ale to nie jest jakaś podstawowa wada związana z teorią obliczeniową. Ta głupota jest tutaj dużo papugowana , ale nie wierzcie im.
Chociaż z pewnością można to zrobić (ten post służy jako dowód istnienia tego niezaprzeczalnego faktu), to nie znaczy, że tak powinno być.
Musisz sam zdecydować, czy masz zamiar napisać, co stanowi dedykowany, specjalny parser HTML z wyrażeń regularnych. Większość ludzi nie jest.
Ale ja jestem. ☻
Ogólne oparte na regeksie rozwiązania do analizowania HTML
Najpierw pokażę, jak łatwo można parsować dowolny kod HTML za pomocą wyrażeń regularnych. Pełny program znajduje się na końcu tego ogłoszenia, ale sercem parsera jest:
Widzisz, jak łatwo to odczytać?
Jak napisano, identyfikuje każdy fragment HTML i informuje, gdzie go znalazł. Możesz łatwo go zmodyfikować, aby zrobić cokolwiek chcesz z dowolnym rodzajem elementu lub dla bardziej konkretnych typów niż te.
Nie mam nieudanych przypadków testowych (po lewej :): Udało mi się uruchomić ten kod na ponad 100 000 plików HTML - każdego z nich mogłem szybko i łatwo zdobyć. Poza tym uruchomiłem go również na plikach specjalnie skonstruowanych w celu przełamania naiwnych parserów.
To nie jest naiwny parser.
Och, jestem pewien, że nie jest idealny, ale nie udało mi się go jeszcze złamać. Wydaje mi się, że nawet gdyby coś zrobiło, poprawka byłaby łatwa do dopasowania ze względu na przejrzystą strukturę programu. Nawet programy z dużym regexem powinny mieć strukturę.
Teraz, gdy to już nie przeszkadza, pozwolę sobie odpowiedzieć na pytanie OP.
Demo rozwiązania zadania PO przy użyciu Regexes
Mały
html_input_rx
program, który zamieszczam poniżej, generuje następujące dane wyjściowe, dzięki czemu można zobaczyć, że analizowanie kodu HTML za pomocą wyrażeń regularnych działa dobrze dla tego, co chcesz zrobić:Analizuj tagi wejściowe, patrz: Brak zła
Oto źródło programu, który wygenerował wynik powyżej.
Proszę bardzo! Nic do tego! :)
Tylko Ty możesz ocenić, czy Twoja umiejętność wyrażeń regularnych zależy od konkretnego zadania analizy. Poziom umiejętności każdego jest inny, a każde nowe zadanie jest inne. W przypadku zadań, w których masz dobrze zdefiniowany zestaw danych wejściowych, wyrażenia regularne są oczywiście właściwym wyborem, ponieważ składanie ich razem jest trywialne, gdy masz do czynienia z ograniczonym podzbiorem HTML. Nawet początkujący wyrażenia regularne powinni obsługiwać te zadania za pomocą wyrażeń regularnych. Wszystko inne to przesada.
Jednak gdy HTML zacznie być mniej dopracowany, gdy zacznie rozgryźć w sposób, którego nie można przewidzieć, ale które są całkowicie legalne, gdy będziesz musiał dopasować więcej różnych rzeczy lub bardziej skomplikowane zależności, w końcu osiągniesz punkt, w którym musisz pracować ciężej, aby uzyskać rozwiązanie wykorzystujące wyrażenia regularne, niż musiałbyś użyć klasy parsującej. To, gdzie spada ten próg rentowności, zależy ponownie od własnego poziomu komfortu z wyrażeniami regularnymi.
Więc co powinienem zrobić?
Nie powiem ci, co musisz zrobić, a czego nie . Myślę, że to źle. Chcę tylko przedstawić Ci możliwości, otwórz trochę oczy. Możesz wybrać, co chcesz zrobić i jak chcesz to zrobić. Nie ma absolutów - i nikt inny nie zna twojej sytuacji tak dobrze jak ty sam. Jeśli wydaje się, że to za dużo pracy, to może tak jest. Wiesz, programowanie powinno być zabawne . Jeśli tak nie jest, być może robisz to źle.
Na mój
html_input_rx
program można patrzeć na wiele ważnych sposobów. Jednym z nich jest to, że rzeczywiście możesz parsować HTML z wyrażeniami regularnymi. Ale innym jest to, że jest o wiele, wiele, znacznie trudniejsze niż prawie ktokolwiek myśli, że tak jest. Może to prowadzić do wniosku, że mój program jest dowodem na to, co powinno nie robić, bo to naprawdę jest zbyt trudne.Nie będę się z tym nie zgadzać. Z pewnością jeśli wszystko, co robię w moim programie, nie ma dla ciebie sensu po jakimś badaniu, nie powinieneś próbować używać wyrażeń regularnych do tego rodzaju zadań. W przypadku określonego HTML wyrażenia regularne są świetne, ale w przypadku standardowego HTML są one równoznaczne z szaleństwem. Cały czas używam klas parsujących, zwłaszcza jeśli to HTML, którego sam nie wygenerowałem.
Regeksy optymalne dla małych problemów z parsowaniem HTML, pesymalne dla dużych
Nawet jeśli mój program jest traktowana jako ilustrację dlaczego należy nie używać regexes w celu analizowania ogólnych HTML - co jest OK, bo trochę rozumie ona być że ☺ - to nadal powinna być niespodzianka więc więcej ludzi złamać strasznie powszechne i paskudny, nieprzyjemny nawyk pisania nieczytelnych, nieustrukturyzowanych i niemożliwych do utrzymania wzorów.
Wzory nie muszą być brzydkie i nie muszą być trudne. Jeśli tworzysz brzydkie wzory, jest to odbicie ciebie, a nie ich.
Fenomenalnie wykwintny język regex
Poproszono mnie o wskazanie, że moje profesjonalne rozwiązanie twojego problemu zostało napisane w Perlu. Czy jesteś zaskoczony? Nie zauważyłeś? Czy to objawienie to bomba?
Prawdą jest, że nie wszystkie inne narzędzia i języki programowania są tak wygodne, wyraziste i potężne, jeśli chodzi o wyrażenia regularne, jak Perl. Istnieje duże spektrum, z których niektóre są bardziej odpowiednie niż inne. Ogólnie rzecz biorąc, łatwiej jest pracować z językami, które wyrażają wyrażenia regularne jako część języka podstawowego zamiast jako bibliotekę. Nie zrobiłem nic z wyrażeniami regularnymi, których nie można zrobić, powiedzmy, w PCRE, chociaż program miałby inną strukturę, gdybyś używał C.
W końcu inne języki będą nadążać za tym, gdzie Perl jest teraz pod względem wyrażeń regularnych. Mówię to, ponieważ kiedy Perl zaczął, nikt inny nie miał takich wyrażeń regularnych jak Perl. Mów co chcesz, ale Perl wyraźnie wygrał: wszyscy skopiowali wyrażenia regularne Perla, choć na różnych etapach ich rozwoju. Perl był pionierem prawie (nie do końca, ale prawie) wszystkiego, na czym dzisiaj polegasz w nowoczesnych wzorach, bez względu na to, jakiego narzędzia lub języka używasz. Więc ostatecznie pozostali będą dogonić.
Ale dotrą tylko do miejsca, w którym Perl był kiedyś, tak jak teraz. Wszystko idzie naprzód. W wyrażeniach regularnych, jeśli nic więcej, do czego prowadzi Perl, inni podążają za nimi. Gdzie będzie Perl, gdy wszyscy w końcu dotrą do miejsca, w którym teraz jest Perl? Nie mam pojęcia, ale wiem, że my też się przeprowadzimy. Prawdopodobnie zbliżymy się do stylu tworzenia wzorów Perla .
Jeśli lubisz tego rodzaju rzeczy, ale chciałbyś użyć ich w Perlu, możesz zainteresować się wspaniałym modułem Regexp :: Grammars Damiana Conwaya . Jest całkowicie niesamowity i sprawia, że to, co zrobiłem tutaj w moim programie, wydaje się tak samo prymitywne, jak moje sprawia, że wzorce, które ludzie łączą ze sobą bez białych znaków i alfabetycznych identyfikatorów. Sprawdź to!
Prosty fragment kodu HTML
Oto pełne źródło parsera, który pokazałem na środku tego wpisu na początku tego postu.
Ja nie sugeruje, że należy korzystać z tego ponad rygorystycznie testowane klasy parsowania. Ale mam dość ludzi udających, że nikt nie może analizować HTML za pomocą wyrażeń regularnych tylko dlatego, że nie. Oczywiście możesz, a ten program jest dowodem tego twierdzenia.
Pewnie, że nie jest to łatwe, ale to jest możliwe!
A próba zrobienia tego jest straszną stratą czasu, ponieważ istnieją dobre klasy analizujące, których powinieneś użyć do tego zadania. Prawidłowa odpowiedź dla osób próbujących parsować dowolny kod HTML nie polega na tym, że jest to niemożliwe. To łatwa i nieuczciwa odpowiedź. Prawidłowa i uczciwa odpowiedź jest taka, że nie powinni próbować, ponieważ zbyt trudno jest zrozumieć od zera; nie powinni łamać sobie pleców, starając się odkryć koło, które działa doskonale.
Z drugiej strony HTML, który mieści się w przewidywalnym podzbiorze, jest wyjątkowo łatwy do parsowania za pomocą wyrażeń regularnych. Nic dziwnego, że ludzie próbują ich używać, ponieważ w przypadku drobnych problemów, być może problemów z zabawkami, nic nie może być łatwiejsze. Dlatego tak ważne jest rozróżnienie dwóch zadań - specyficznego od ogólnego - ponieważ niekoniecznie wymagają tego samego podejścia.
Mam nadzieję, że w przyszłości zobaczę bardziej sprawiedliwe i uczciwe traktowanie pytań dotyczących HTML i wyrażeń regularnych.
Oto mój leksykon HTML. Nie próbuje wykonać sprawdzania poprawności; po prostu identyfikuje elementy leksykalne. Możesz myśleć o tym bardziej o chunkrze HTML niż parserze HTML. Nie wybacza bardzo zepsutego HTML, choć wprowadza pewne bardzo niewielkie poprawki w tym kierunku.
Nawet jeśli nigdy nie parsujesz pełnego kodu HTML (a dlaczego miałbyś? To rozwiązany problem!), Ten program ma wiele fajnych bitów wyrażeń regularnych, z których, jak sądzę, wiele osób może się wiele nauczyć. Cieszyć się!
źródło
//input[@type="hidden"]
. Lub jeśli nie chcesz używać Xpath, po prostu pobierz wszystkie dane wejściowe i filtruj, które są ukrytegetAttribute
.Wolę # 2.
Wynik:
źródło
W duchu rozwiązania leksykalnego Toma Christiansena, oto link do pozornie zapomnianego artykułu Roberta Camerona z 1998 roku, REX: XML Shallow Parsing with Regular Expressions.
http://www.cs.sfu.ca/~cameron/REX.html
Jeśli lubisz czytać o wyrażeniach regularnych, praca Camerona jest fascynująca. Jego pisanie jest zwięzłe, dokładne i bardzo szczegółowe. Nie tylko pokazuje, jak skonstruować wyrażenie regularne REX, ale także podejście do tworzenia dowolnego złożonego wyrażenia regularnego z mniejszych części.
Używam i wyłączam wyrażenie regularne REX od 10 lat, aby rozwiązać problem, o który pytał pierwotny plakat (jak dopasować ten konkretny tag, ale nie inny bardzo podobny tag?). Stwierdziłem, że regex, który opracował, jest całkowicie niezawodny.
REX jest szczególnie przydatny, gdy skupiasz się na szczegółach leksykalnych dokumentu - na przykład podczas przekształcania jednego rodzaju dokumentu tekstowego (np. Zwykłego tekstu, XML, SGML, HTML) w inny, w którym dokument może być nieprawidłowy, dobrze uformowany lub nawet parsowalny przez większość transformacji. Pozwala celować w wyspy znaczników w dowolnym miejscu dokumentu, nie zakłócając reszty dokumentu.
źródło
Chociaż uwielbiam treść pozostałych odpowiedzi, tak naprawdę nie odpowiedzieli na pytanie bezpośrednio lub tak poprawnie. Nawet odpowiedź Platinum była zbyt skomplikowana, a także mniej wydajna. Więc byłem zmuszony to powiedzieć.
Jestem wielkim zwolennikiem Regex, jeśli jest prawidłowo stosowany. Ale ze względu na piętno (i wydajność) zawsze stwierdzam, że dobrze sformatowany XML lub HTML powinien używać parsera XML. A jeszcze lepsza wydajność to parsowanie ciągów, choć istnieje granica między czytelnością, jeśli to wymyka się spod kontroli. To jednak nie jest pytanie. Pytanie brzmi, jak dopasować znacznik wejściowy typu ukrytego. Odpowiedź to:
W zależności od gustu jedyną opcją wyrażenia regularnego, którą musisz uwzględnić, jest opcja ignorowania.
źródło
<input type='hidden' name='Oh, <really>?' value='Try a real HTML parser instead.'>
>
pola w nazwie są prawie zerowe, rzeczywiście jest możliwe, aby istniał>
uchwyt akcji. EG: wbudowane wywołanie javascript we właściwości OnClick. Biorąc to pod uwagę, mam parser XML dla tych, ale mam również Regex dla tych, w których dokument, który dostałem, jest zbyt zawalony, aby parsery XML mogły go obsłużyć, ale Regex może. Ponadto nie o to pytano. Nigdy nie spotkasz się z takimi sytuacjami z ukrytym wkładem, a moja odpowiedź jest najlepsza.Ya, <really>!
./>
jest XML-ism; nie jest wymagany w żadnej wersji HTML, z wyjątkiem XHTML (który nigdy tak naprawdę nie zyskał dużej przyczepności i został prawie zastąpiony przez HTML5). I masz rację, że jest tam dużo nieporządnego, niepoprawnego HTML, ale dobry parser HTML ( nie XML) powinien być w stanie poradzić sobie z większością z nich; jeśli nie, najprawdopodobniej nie będą to również przeglądarki.możesz spróbować:
i dla bliższego rezultatu możesz spróbować:
możesz przetestować wzór wyrażenia regularnego tutaj http://regexpal.com/
te patty są do tego dobre:
i dla losowej kolejności
type
,name
ivalue
możesz użyć tego:lub
na to :
`
tak przy okazji, myślę, że chcesz czegoś takiego:
to nie jest dobre, ale działa w jakikolwiek sposób.
przetestuj w: http://regexpal.com/
źródło
Chciałbym użyć
**DOMDocument**
do wyodrębnienia kodu HTML.BTW, możesz to przetestować tutaj - regex101.com. Pokazuje wynik w czasie rzeczywistym. Niektóre reguły dotyczące Regexp: http://www.eclipse.org/tptp/home/downloads/installguide/gla_42/ref/rregexp.html Reader .
źródło
załóżmy, że zawartość html jest przechowywana w html ciągu, a następnie aby ukryć wszystkie dane wejściowe zawierające typ, możesz użyć wyrażenia regularnego
powyższe wyrażenie regularne znajduje się
<input
po dowolnej liczbie znaków, dopóki się nie pojawitype="hidden"
lub wpisz = „ukryty”, a następnie dowolna liczba znaków, aż się pojawi>
/ g powiedz wyrażenie regularne, aby znaleźć każdy podciąg pasujący do podanego wzorca.
źródło