@lala demandé dans Comment utiliser la substitution regex <*> ? à propos de saisir URL depuis HTML . Voici un peu plus de détails sur trois réponses proposées. Tout d'abord, la clause de non-responsabilité : aucun de ces exemples ne fait un bon travail d'analyse HTML, donc tous peuvent trouver des URL qui ne sont pas vraiment là et manquer d'autres URL qui sont vraiment là.
/*
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.
*/
Les problèmes d'analyse HTML consistent principalement à trouver des balises de début et de fin correspondantes et à examiner les données entre elles. Tout le JSL présenté ici peut être déclenché par des fonctionnalités HTML. Mais, cela pourrait être assez bon; faites vos propres tests. Regarde aussi Belle soupe ce qui pourrait être une meilleure réponse.
Voici un extrait d'une page Web HTML montrant un lien (la balise ) avec une URL (la partie href=) et un peu de texte (la partie Discussions) qui seront visibles sur la page.
< 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 TextBalise avec URL et texte
L'objectif est de créer un tableau de données des URL et du texte du lien, un par ligne. Une page Web typique peut contenir environ 100 liens et contenir un demi-mégaoctet de texte. Un lent Une façon d'attaquer le problème (non illustré) est d'écrire une expression régulière simple qui trouve un lien à la fois, supprime le lien du texte et répète jusqu'à ce qu'il n'y en ait plus. S'il n'y en a qu'un ou deux, tant mieux. Mais s'il pouvait y en avoir des centaines, alors quelques centaines de mégaoctets de données sont manipulés et recherchés.
Un moyen plus rapide consiste à rechercher dans les données, en avançant toujours, en construisant la table de données au fur et à mesure que des liens sont trouvés. Le premier exemple utilise la fonction contains() qui a un troisième argument pour spécifier une position de départ. Contient() renvoie également une position trouvée. En mettant à jour la position de départ juste au-delà de la position trouvée, contains() peut parcourir efficacement le texte sans avoir besoin de sauvegarder ou de modifier le texte.
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>
Le cœur de ce code est la ligne
while( (p1 = Contains( txt, "<A></A>
qui fait un tas de travaux : il utilise pos dans le 3ème argument pour ignorer tout travail précédent, il trouve le prochain rien n'a été trouvé , donc la boucle s'arrête. La prochaine ligne
p4 = Contains( txt, ">", p1 + 3 );
recherche le > correspondant qui termine la balise
p5 = Contains( txt, "", p4 + 1 );
p5 pointera vers la balise qui termine le texte du lien. De nombreuses balises HTML, mais pas toutes, fonctionnent ainsi, une balise de début sans le / et une balise de fin avec la barre oblique. Parfois, les balises de début et de fin sont identiques, en utilisant , mais ce JSL ignore cette possibilité.
L'instruction if détermine si quelque chose a été trouvé, et si c'est le cas, récupère la description comme celle-ci
desc = Substr( txt, p4 + 1, p5 - p4 - 1 );
p4 et p5 pointent le > et <. donc p4+1 est le premier caractère de description, et p5-p4-1 est la longueur de la description. La ligne suivante nettoie la description en supprimant les balises intégrées
desc = Regex( desc, "<[^>]*>", "", globalreplace );
GlobalReplace signifie que la regex trouvera le modèle, remplacera ce texte par rien, autant de fois que possible. Le modèle correspond à <, suivi de zéro ou plusieurs caractères qui ne sont pas >, suivi de > qui peut être une balise 
ou un groupe de balises de style de texte. Le résultat final est le texte de la balise sans aucune image/couleur/police/etc.
Les deux lignes suivantes sont similaires, pour saisir l'URL plutôt que la description
p1 et p4 (voir commentaire) sont les positions entières des balises de lien ; linktext est la balise de lien comprenant un certain nombre de bits indésirables. le hreftext utilise regex() pour extraire uniquement l'URL entre les guillemets href ou les apostrophes. Le modèle regex utilise la backref \1 pour s'assurer que l'apostrophe ou le guillemet de fin correspond à celui de début. La première parenthèse ouverte dans le modèle regex crée un groupe de capture (pour \1) qui correspond à " ou '. La deuxième parenthèse ouverte est le groupe de capture (pour \2) qui correspond, avançant à contrecœur aussi loin que nécessaire pour faire correspondre les délimiteurs. La troisième parente ouverte est le groupe de capture 3 ; les parenthèses et le regroupement ne sont pas vraiment nécessaires. Le résultat, \2, n'est que l'URL.
Tout sauf fait : s'il y a une description, ajoutez une ligne au tableau, puis, très important, avancez la variable pos !
Max s'assure qu'il ne recule pas à la fin et ne reste pas coincé dans une boucle.
Le code ci-dessus est assez rapide, mais c'est encore mieux.