IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

Expression régulière pour les Urls


Sujet :

JavaScript

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut Expression régulière pour les Urls
    Bonjour,

    Voilà j'aimerais (en JavaScript) remplacer toutes les urls par des liens <a href=...>...</a>

    Donc j'ai une epxression régulière pour capter les liens :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var replacePattern1 = /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    var replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
    Seulement le problème c'est que si une url est déjà dans un lien il la capte quand même.

    Du coup j'aimerais changer l'expression régulière pour lui dire de ne pas traiter les liens s'il ya un '>' devant le http (donc quand l'url est déjà dans une balise <a href=...>...</a>).

    J'ai essayé ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var replacePattern1 = /^[^>](\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    var replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>');
    Du coup il ne traite plus les url qui sont déjà dans un lien <a> mais par contre il ne traite plus non plus les url qui ne sont pas sous forme de lien <a> :'(

    Avez-vous une idée de comment faire une expression régulière qui fasse ce que je souhaite?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 669
    Points
    66 669
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var replacePattern1 = /^[^>]\s*((https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Merci spacefrog, ça marche bien pour ne pas prendre les urls précédées de > comme :
    >http://www.google.com


    Par contre ça ne prend plus non plus les url qui ne sont pas précédées du > comme :
    http://www.google.com

    (même avec des espaces devant ou derrière).

    Résultat des tests : http://awesomescreenshot.com/014dvli38

    Donc retour à la case départ

  4. #4
    Rédacteur/Modérateur

    Avatar de SpaceFrog
    Homme Profil pro
    Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Inscrit en
    Mars 2002
    Messages
    39 640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Développeur Web Php Mysql Html Javascript CSS Apache - Intégrateur - Bidouilleur SharePoint
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2002
    Messages : 39 640
    Points : 66 669
    Points
    66 669
    Billets dans le blog
    1
    Par défaut
    arf ...évidemment,
    et avec une assertion ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var replacePattern1 = /^(?!=>)\s*((https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
    Ma page Developpez - Mon Blog Developpez
    Président du CCMPTP (Comité Contre le Mot "Problème" dans les Titres de Posts)
    Deux règles du succès: 1) Ne communiquez jamais à quelqu'un tout votre savoir...
    Votre post est résolu ? Alors n'oubliez pas le Tag

    Venez sur le Chat de Développez !

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Toujours pas

    Je teste avec ceci : http://www.regular-expressions.info/...ptexample.html

    Et le met comme subject string celle ci :
    _http://www.google.be/_

    (les _ étant en fait des espaces).

    Je commence à croire que c'est tout bonnement impossible... :s

  6. #6
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Je crois qu'il y a un problème de syntaxe avec ton assertion Spaffy. En plus, on peut pas regarder en arrière avec les assertions. Et pour ajouter au drame, on peut pas faire de référence arrière en JavaScript…

    Moi je propose ça mais c'est pas parfait non plus : s'il y a une balise, même autre que <a>, autour du lien, il n'est pas traité…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var replacePattern1 = /([^<>"'\s]\s*)(\b(https?):\/\/[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|])(\s*[^<>"'\s])/gi;
    var replacedText = inputText.replace(replacePattern1, '$1<a href="$2" target="_blank">$2</a>$4');
    Au fait j'ai viré l'option m : vu qu'on ne se sert pas des ancres ^ et $, elle est inutile. Et j'ai aussi remplacé tous les [A-Z0-9_] par des [\w].

    Sinon je pense que pour cibler précisément le problème, une regex ne suffira pas. Il faut scripter un peu autour…
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Prendre le taureau par la queue
    Citation Envoyé par Watilin Voir le message
    En plus, on peut pas regarder en arrière avec les assertions. Et pour ajouter au drame, on peut pas faire de référence arrière en JavaScript…
    Pourquoi dans ce cas ne pas plutôt exclure par la fin plutôt que par le début ? Ne pas autoriser "> après le href et </a> après le titre.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Exemple de code et méthode alternative
    Citation Envoyé par scriptiz Voir le message
    Voilà j'aimerais (en JavaScript) remplacer toutes les urls par des liens <a href=...>...</a>
    C'est un problème assez commun il me semble. T'as regardé du côté de CodeS-SourceS & Cie ? Sinon un compromis c'est de faire un split au niveau des espaces du texte à traiter puis d'utiliser une expression régulière sur chaque chaîne et enfin d'assembler tout ce petit monde.

  9. #9
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Citation Envoyé par ohnomorejmmings Voir le message
    Pourquoi dans ce cas ne pas plutôt exclure par la fin plutôt que par le début ? Ne pas autoriser "> après le href et </a> après le titre.
    C'est pas si évident de détecter le ">, il peut y avoir d'autres attributs, comme par exemple target.

    Moi je suis parti sur une autre idée : quand je tombe sur une url, que je détecte avec la regex, je rembobine jusqu'au dernier < avec lastIndexOf, et je détecte simplement si c'est une balise <a> ouvrante :
    Dans ce cas je ne fais rien. Dans tous les autres cas, je transforme l'url en lien. Avec cette méthode je considère à la fois les balises autres que <a> et les liens qui concernent une autre url rencontrée plus tôt (car il y aurait une balise fermante).

    Et voilà ce que ça donne :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    var replacePattern1 = /\bhttps?:\/\/[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|]/gi;
    var previousIndex = 0;
    var replacedText = '';
    var matching;
     
    while (matching = replacePattern1.exec(inputText)) {
     
    	var url = matching[0];
     
    	// j'ajoute le texte qui n'a pas besoin d'être traité
    	var index = inputText.indexOf(url, previousIndex);
    	replacedText += inputText.substring(previousIndex, index);
     
    	// je rembobine jusqu'au dernier "<"
    	var rewound = inputText.substring(inputText.lastIndexOf('<', index), replacePattern1.lastIndex);
     
    	if (/<\s*a/i.test(rewound)) {
    		// je ne fais rien
    		replacedText += url;
    	} else {
    		// je transforme le lien
    		replacedText += '<a href="' + url + '" target="_blank">' + url + '</a>';
    	}
     
    	previousIndex = replacePattern1.lastIndex;
    }
    replacedText += inputText.substr(previousIndex);
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Merci Watilin

    Mais de nouveau je ne parviens pas à faire des match avec les urls valident sur le testeurs d'url que j'ai donné plus haut :s

    Tu l'a testée sur des liens toi?

  11. #11
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Bien sûr, voilà mon jeu de tests :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    var inputText = 'Test 1 : test de la regex, transformer : https://www.machin.org/le%20singe.ape?num=0,42#hash <br />\n\
    Test 2 : href, ne pas transformer : <a href="http://chose.fr">chose</a><br />\n\
    Test 3 : balise a, ne pas transformer : <a>http://www.truc.net</a><br />\n\
    Test 4 : transformer après une <em>balise quelconque :</em> http://www.bidule.com';

    Je pense qu'il faut retirer les / avec ton testeur.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Ah bah en effet ce testeur n'est vraiment pas bon il déconne tout le temps, du coup je teste directement dans mon code maintenant

    Mais bon je galère là, toujours des problèmes

    Avec ton code avec le lastIndexOf ça me retire carrèment les messages sans liens Et ça retire aussi ce qui suit le dernier lien bien souvent ^^

    Par contre pour ceci c'est pas mal bien qu'avec quelques bugs

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    var replacePattern1 = /([^<>"'\s]\s*)(\b(https?):\/\/[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|])(\s*[^<>"'\s])/gi;
    var replacedText = inputText.replace(replacePattern1, '$1<a href="$2" target="_blank">$2</a>$4');
    Ca fonctionne presque bien hormis le fait qu'il ne me traite pas complètement certains liens, et que parfois il ne traite que le premier :s

    Donc voici ma fonction linkify :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    function linkify(inputText) {
    	var replacePattern1 = /([^<>"'\s]\s*)(\b(https?):\/\/[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|])(\s*[^<>"'\s])/gi;
    	var replacedText = inputText.replace(replacePattern1, '$1<a href="$2" target="_blank">$2</a>$4');
     
    	return replacedText;
    }
    Et voici quelques exemples de ce qu'elle reçoit (précédé par Before et de ce qu'elle renvoie (précédé par After) :

    Exemple où seul le premier lien est transformé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Before :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour Anael,
    <br>
    <br>Je me permet de faire un petit test : http://www.google.be    http://google.be 
    <br>
    <br>Héhé si ça fonctionne c'est cool : www.google.be www.gmail.com<br> 
                      <br>
     
     
    After :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour Anael,
    <br>
    <br>Je me permet de faire un petit test : <a href="http://www.google.be" target="_blank">http://www.google.be</a>    http://google.be 
    <br>
    <br>Héhé si ça fonctionne c'est cool : www.google.be www.gmail.com<br> 
                      <br>
    Exemple où un lien n'est pas transformé complètement (le e final n'est pas prit en compte :s
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Before :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour http://google.be
    <br>
    <br>Yeah<br> 
                      <br>
     
     
    After :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour <a href="http://google.b" target="_blank">http://google.b</a>e
    <br>
    <br>Yeah<br> 
                      <br>

    Exemple où tous les liens sont prit en comptes, mais où les m du .com ne sont pas repris dans l'url :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Brefore :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour ceci est un http://www.test.net afin de vérifier si http://www.google.com
    <br>
    <br>Tout fonctionne-t-il bien? http://www.super.com
    <br>
    <br>Au revoir<br> 
                      <br>
     
     
    After :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Bonjour ceci est un <a href="http://www.test.net" target="_blank">http://www.test.net</a> afin de vérifier si <a href="http://www.google.co" target="_blank">http://www.google.co</a>m
    <br>
    <br>Tout fonctionne-t-il bien? <a href="http://www.super.co" target="_blank">http://www.super.co</a>m
    <br>
    <br>Au revoir<br> 
                      <br>

    Et un petit dernier qui n'est de nouveau pas complet au niveau du lien :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Brefore :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Test : http://www.supersite.net/dossier/fonctions.js<br> 
                      <br>
     
     
    After :
    <br> <b>Attention, nous ne demanderons jamais votre mot de passe quoi qu'il arrive, si ce message vous le demande, veuillez ne pas y rèpondre et nous en faire part immèdiatement</b><br>  <br>  Test : <a href="http://www.supersite.net/dossier/fonctions.j" target="_blank">http://www.supersite.net/dossier/fonctions.j</a>s<br> 
                      <br>

    Sinon ce qui est génial c'est qu'il ne traite pas les liens déjà existant ça c'est vraiment parfait, mais ce qu'il faudrait c'est qu'il traite bien les url qu'il trouve :s Je suis vraiment hors jeu pour ce niveau de Regex ^^

  13. #13
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Points : 6 755
    Points
    6 755
    Par défaut
    Oups. J'avais bêtement oublié de traiter la fin de la chaîne dans mon code. C'est corrigé !

    Pour la version que tu as choisie, et les tests que tu as faits, je vois trois cas :
    1– les liens se suivent. Les parties $1 et $4 de la regex se chevauchent d'un lien à l'autre, du coup le second passe à la trappe. On va s'en sortir avec la proposition de ohnomorejmmings : utiliser une assertion à la fin.

    2– Pour les liens qui ne commence pas par http, c'est normal qu'ils ne soient pas transformés, c'était déjà le comportement de ta regex de départ.

    3– le dernier caractère est oublié. Ça arrive aux fins de ligne : le moteur de regex doit trouver un caractère qui correspond à [^<>"'\s], or il n'y en plus dans la ligne, alors il en grignote un de l'url. Pour corriger ça il suffit de rajouter un point d'interrogation.

    Ça plus d'autres problèmes, par exemple un texte qui commence par un lien, ça donne une regex comme ça :
    Code regex : Sélectionner tout - Visualiser dans une fenêtre à part
    /((?:^|[^<>"'])\s*)((https?):\/\/[-\w+&@#\/%?=~|!:,.;]*[-\w+&@#\/%=~|])(?=\s*[^<>"'\s]?)/gim
    Comme l'assertion finale n'est pas capturante, on ne doit plus utiliser $4 :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    return inputText.replace(replacePattern1, '$1<a href="$2" target="_blank">$2</a>');
    N'hésite pas à faire d'autres tests… Comme tu l'as vu, j'oublie des cas
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    13
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2009
    Messages : 13
    Points : 10
    Points
    10
    Par défaut
    Et bien sérieusement je ne pensais pas que c'était faisable je ne sais pas comment te remercier Watilin

    J'ai testé tout mes cas et bien d'autres et n'ai rencontré aucun problème

    Pour les liens qui commencent par www. j'avais oublié que c'était voulu, seuls ceux qui ont http seront transformés.

    Donc voilà je pense que c'est désormais réglé, un tout tout grand merci à tout le monde pour votre aide elle fut vraiment précieuse!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. expression régulière pour les url
    Par phpines dans le forum Général Python
    Réponses: 2
    Dernier message: 17/04/2013, 14h49
  2. Trouver une expression régulière pour les valeurs des noeuds XML
    Par Motin dans le forum Format d'échange (XML, JSON...)
    Réponses: 11
    Dernier message: 05/10/2011, 17h51
  3. [RegEx] Expression régulière pour les balises HTML
    Par meloo dans le forum Langage
    Réponses: 3
    Dernier message: 09/07/2009, 15h23
  4. Pb d'expression Réguliére : pour les amateurs
    Par tnodev dans le forum Général Java
    Réponses: 10
    Dernier message: 16/02/2008, 22h14
  5. [RegEx] Expression régulière pour les retours de lignes
    Par Marshall_Mathers dans le forum Langage
    Réponses: 3
    Dernier message: 01/03/2007, 09h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo