@lala nachgefragt Wie kann die Regex-Ersetzung <*> verwendet werden? übers Greifen URLs aus HTML . Hier finden Sie etwas mehr Details zu drei vorgeschlagenen Antworten. Zunächst der Haftungsausschluss: Keines dieser Beispiele kann HTML ordnungsgemäß analysieren, sodass alle URLs finden können, die nicht wirklich vorhanden sind, und andere URLs übersehen, die tatsächlich vorhanden sind.
/*
THIS IS NOT AN HTML PARSER
HTML parsers are hard to write. There are better ways.
Neither of these JSL ideas can properly skip comments or
many other HTML tags that should be skipped. They will
find things they shouldn't and miss other things they
should find. They've only been minimally tested on one site.
This code is presented as "how can I use contains() vs patmatch()
to efficiently work through a large string looking for something?"
The second example is FIVE TIMES FASTER and a LITTLE MORE ACCURATE.
The third example uses text explorer to grab links. I don't think
there is a pre-existing regex for the link text descriptions. It works
very similar to this code; it is NOT an HTML parser either.
If you can use python, you might want to investigate "beautiful soup".
I've not used it, but believe it addresses the "hard to write" issue.
*/
Die Probleme beim Parsen von HTML bestehen hauptsächlich darin, passende Start- und End-Tags zu finden und die Daten zwischen ihnen zu betrachten. Alle hier vorgestellten JSLs können durch HTML-Funktionen gestört werden. Aber es könnte gut genug sein; Machen Sie Ihre eigenen Tests. Siehe auch Wunderschöne Suppe Das könnte eine bessere Antwort sein.
Hier ist ein Ausschnitt aus einer HTML-Webseite, der einen Link (das -Tag) mit einer URL (den href=-Teil) und etwas Text (den Diskussionsteil) zeigt, der auf der Seite sichtbar sein wird.
< a > tag with URL and Text< a > tag with URL and Text< a > tag with URL and Text< a > tag with URL and Text< a > tag with URL and Text-Tag mit URL und Text
Das Ziel besteht darin, eine Datentabelle der URLs und des Linktexts zu erstellen, eine pro Zeile. Eine typische Webseite kann etwa 100 Links haben und ein halbes Megabyte Text umfassen. Eins langsam Eine Möglichkeit, das Problem anzugehen (nicht gezeigt), besteht darin, einen einfachen regulären Ausdruck zu schreiben, der jeweils einen Link nach dem anderen findet, den Link aus dem Text zu entfernen und dies zu wiederholen, bis kein weiterer Link mehr gefunden werden kann. Wenn es nur ein oder zwei sind, großartig. Aber wenn es Hunderte sein könnten, dann werden ein paar Hundert Megabyte an Daten manipuliert und durchsucht.
Eine schnellere Möglichkeit besteht darin, die Daten immer weiter zu durchsuchen und die Datentabelle zu erstellen, sobald Links gefunden werden. Das erste Beispiel verwendet die Funktion enthält(), die über ein drittes Argument zur Angabe einer Startposition verfügt. Contains() gibt auch eine gefundene Position zurück. Indem die Startposition knapp hinter der gefundenen Position aktualisiert wird, kann contains() den Text effizient durchsuchen, ohne den Text sichern oder ändern zu müssen.
u = "https://community.jmp.com/t5/Discussions/bd-p/discussions";
txt = Load Text File( u );
// a link on a page has at least two parts:
// the URL and some descriptive text.
// <A ...="" href="https://community.jmp.com/url" ...="" target="_blank"> descripton </A>
// p1 p4 p5
// using contains and regex. "<A>", p1 + 3 ); // find the end of the opening tag
p5 = Contains( txt, "</A>", p4 + 1 ); // find the ending tag
if( p5 > p4, // as long as the end is not zero, we found one, see break() below
desc = Substr( txt, p4 + 1, p5 - p4 - 1 ); // the visible link description. Images can be here too.
desc = Regex( desc, "<[^>]*>", "", globalreplace ); // remove span, image, etc tags
linktext = Substr( txt, p1, p4 - p1 + 1 ); // <A href="https://community.jmp.com/" target="_blank">
hreftext = Regex( linktext, "href\s*=\s*(\!"|')(.*?)(\1)", "\2" );// use regex to get the href value
if( !Is Missing( hreftext ), // sometimes there isn't one
dt << addrows( 1 );
irow = N Rows( dt );
dt:link[irow] = hreftext;
dt:description[irow] = desc;
);
, // else
Break() // no more end tags. there is maybe a mess of javascript.
);
pos = Max( pos, p5 + 3 ); // advance past the one just found
);
stoptime = Tick Seconds();
dt << endDataUpdate;
Show( stoptime - starttime ); </A>
Das Herzstück dieses Codes ist die Zeile
while( (p1 = Contains( txt, "<A></A>
Das erledigt eine Reihe von Aufgaben: Es verwendet pos im dritten Argument, um alle vorherigen Arbeiten zu überspringen, es findet das nächste Nichts gefunden , sodass die Schleife stoppt. Die nächste Zeile
p4 = Contains( txt, ">", p1 + 3 );
sucht nach dem passenden >, das das p5 = Contains( txt, "", p4 + 1 );
p5 verweist auf das -Tag, das den Linktext beendet. Viele, aber nicht alle HTML-Tags funktionieren so: ein Start-Tag ohne / und ein End-Tag mit Schrägstrich. Manchmal sind das Start- und End-Tag identisch und verwenden , aber diese JSL ignoriert diese Möglichkeit.
Die if-Anweisung ermittelt, ob etwas gefunden wurde, und greift in diesem Fall die Beschreibung wie folgt auf
desc = Substr( txt, p4 + 1, p5 - p4 - 1 );
p4 und p5 zeigen auf > und <. also ist p4+1 das erste Beschreibungszeichen und p5-p4-1 ist die Länge der Beschreibung. Die nächste Zeile bereinigt die Beschreibung, indem eingebettete Tags entfernt werden
desc = Regex( desc, "<[^>]*>", "", globalreplace );
GlobalReplace bedeutet, dass die Regex das Muster findet und diesen Text so oft wie möglich durch nichts ersetzt. Das Muster entspricht <, gefolgt von null oder mehr Zeichen, die nicht > sind, gefolgt von >, bei dem es sich möglicherweise um ein 
-Tag oder eine Reihe von Textstil-Tags handelt. Das Endergebnis ist der Text des Tags ohne Bild/Farbe/Schriftart usw.
Die nächsten beiden Zeilen sind ähnlich und dienen zum Erfassen der URL und nicht der Beschreibung
p1 und p4 (siehe Kommentar) sind die gesamten Link-Tag-Positionen; Linktext ist das Link-Tag, das eine Reihe unerwünschter Bits enthält. Der hreftext verwendet regex(), um nur die URL zwischen den href-Anführungszeichen oder Apostrophen zu extrahieren. Das Regex-Muster verwendet die Backref \1, um sicherzustellen, dass das abschließende Apostroph oder Anführungszeichen mit dem führenden übereinstimmt. Das erste offene Paren im Regex-Muster erstellt eine Erfassungsgruppe (für \1), die mit „ oder „ übereinstimmt. Der zweite offene Paren ist die Capture-Gruppe (für \2), die übereinstimmt und sich widerstrebend so weit vorwärts bewegt, wie es für die Übereinstimmung zwischen den Trennzeichen erforderlich ist. Der dritte offene Paren ist Erfassungsgruppe 3; Die Parens und die Gruppierung werden nicht wirklich benötigt. Das Ergebnis \2 ist nur die URL.
Alles andere als erledigt: Wenn es eine Beschreibung gibt, fügen Sie der Tabelle eine Zeile hinzu und rücken Sie dann, was sehr wichtig ist, die Variable pos vor!
Max achtet darauf, dass es am Ende nicht rückwärts geht und in einer Schleife stecken bleibt.
Der obige Code ist ziemlich schnell, aber dieser ist noch besser.