Les motifs ne sont pas tous pris en compte !!

Résolu
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 - 18 juil. 2009 à 19:16
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 - 23 juil. 2009 à 01:05
Bonjour.

Voici la regex qui me pose problème :
var regex = new RegExp(">([^<]*)?("+searchTerms[i]+")([^>]*)?<","ig");

Cette (Ce ?) regex récupère le mot identifié par la variable searchTerms[i] tant qu'il n'est pas inclus dans des balises html.

Cela marche à peu près sauf lorsque j'ai deux occurences du mot cherché non séparées par des balises html.

Exemple si on cherche le mot handicap dans le texte ci-dessous :
La Convention des Nations-Unies sur les Droits des Personnes Handicapées : Impact et opportunités pour les Personnes Handicapées dans les pays en développement



Au lieu de retourner les deux occurences, le regex retourne seulement la dernière !


Avez vous la solution au problème ??


Merci d'avance pour votre aide .

39 réponses

cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
21 juil. 2009 à 10:08
j'ai compris !!
Comme quoi c'est pas forcément les explications les plus courtes les meilleures

Un de mes problèmes était bien au niveau de la différence entre ([^<]*)? et ([^<]*?). Ca m'explique pourquoi ma regex n'était pas bonne.

J'ai une dernière (?) question cependant. Quand tu dis que le "|" ne retient que l'expression la plus longue, c'est par rapport au rendu html qu'on calcule cette longueur? Dans ce cas puisque ce qui est à l'intérieur d'une balise ne s'affiche pas en html, forcément ca sera plus court que du simple texte !
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
21 juil. 2009 à 13:35
En fait je ne voyais pas ce que venais faire cette histoire de longueur sur ta regex mais puisque ce n'est pas par rapport à la longueur que s'effectue la sélection avec le "|", eh bien oublions...

Par contre l'histoire de "priorité au 1er", m'explique le pourquoi du comment de ta regex :
- <[^>]*?handicap.*?> ->selectionne tous les mots "handicap" à l'intérieur des balises
-|handicap ->selectionne les mots "handicap" restants, cad ceux qui ne sont pas compris dans les balises puisque sinon ils seraient pris en compte dans la premiere partie de la regex

Donc si on inversait,handicap | <[^>]*?handicap.*?>, voudrait dire qu'on prendrait tous les mots, qu'ils soient entre des balises ou pas (->on pourrait donc supprimer la 2eme partie qui ne servirait pas à grand chose !!).


Je me trompe ? Je ne pense pas...
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
21 juil. 2009 à 14:02
tu as tout saisi.


Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
21 juil. 2009 à 14:31
Je suis trop fort !!!

Non sans rire merci mille fois Renfield car tu m'as permis
1/ de résoudre mon problème
2/ de mieux comprendre les regex (outil qui, je le redis peut être, n'est vraiment pas facile)


A la prochaine sur le forum

[SUJET DEFINITIVEMENT RESOLU]


Vive les forums !
Romain
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
21 juil. 2009 à 20:31
Je crois que je n'emploierai plu jamais le mot "DEFINITIVEMENT" !!
Et oui je suis désolé mais ca ne marche pas !!

En fait le mot cherché est quand même comptabilisé même quand il est dans des balises html.

Voici la page ma page où je travaille, pour que tu puisses verifier :
Tapez le texte de l'url ici.

Y'a un truc tres bizarre quand tu affiche le code source de la page : les modifications javascript pour surligner le mot n'apparaissent pas ! C'est normal ?
Autre maniere de voir le probleme :
les textes que tu vas voir sont souvent le debut d'un article. C'est pour ce la qu'on a des liens à la fin de l'article de la forme : "[...]"
Si tu tapes handicap dans la zone de recherche, tu verras que le premier lien marche. Mais les suivants ne marchent pas. Et pour cause ! Dans le lien j'ai mis le mot cherché en parametre de l'url. Donc ca veut dire que le regex intervient la dessus !
Exemple :
[...]

Ce lien qui marchait avant ne marche plus et si j'enlève mon code javascript avec la regex ca remarche. Donc le problème est bien la !

Je sais que tu m'as déjà beaucoup aidé mais j'ai encore besoin de ton aide !


Merci tres beaucoup par avance (c'est francais, ca ?? )
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
21 juil. 2009 à 20:40
Je te redonnes la regex :
      var regex = new RegExp("<[^>]+?("+searchTerms[i]+").*?>|("+searchTerms[i]+")","ig"); 


Et voici le code pour remplacer le mot s'il correspond :
element.innerHTML = tempinnerHTML.replace(regex,'$2')
;

element.innerhtml (et tempinnerHTML) contient tout le texte html de ma page qui est compris entre des balises définies (et ce code contient les balises html puisque je fais un innerhtml)
Le parametre regex est la regex du dessus.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 00:36
j'ignore si ton moteur est plus efficace que le mien, mais normallement, on doit pouvoir utiliser un lookbehind...

http://www.regular-expressions.info/lookaround.html


Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
22 juil. 2009 à 08:49
Si j'ai bien compris il s'agit de revenir en arriere dans le chaine lorsqu'on rencontre un motif qui est précédé de ?<! ou ?<=.

Ca changerait quoi au problème ?

J'ai fait quelques essais comme ceci :
var regex = new RegExp("<(?<![^>]+?)"+searchTerms[i]+".*?>|("+searchTerms[i]+")","ig");


Mais ca n'a pas marché !!

Puis j'ai regardé à la fin de ton lien il y avait ceci :
The only regex engines that allow you to use a full regular expression inside lookbehind are the JGsoft engine and the .NET framework RegEx classes.
Finally, flavors like JavaScript, Ruby and Tcl do not support lookbehind at all, even though they do support lookahead.


Ma regex est dans une fonction javascript donc j'imagine que ca ne marchera pas...
Je me trompe ??
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 10:00
on doit utiliser le même moteur, dommage, je peux pas tester non plus, sauf a passer en .Net

le lookbehind permettrait de conditionner ce qu'il y a avant la chaine.

c'est pile poil ce qu'il faudrait pour ne pas patcher les balises.


Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 10:14
au pire, rien ne t'oblige a utiliser la méthode Replace...

libre a toi de reconstruire l'HTML a la volée, en ajoutant ou non de la couleur, en regardant chaque Match trouvé, en fonction du premier caractère (ne pas colorier si le premier caractère du match en cours est un < )

Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
22 juil. 2009 à 13:14
Euh j'ai pas trop compris ton dernier message mais une chose est sure ca doit être possible avec le lookbehind ou sans.
J'ai vu pleins de discussions à ce sujet donc il doit bien y en avoir qui y sont arrivés .
Je vais aller faire un tour sur le net et je te retiens au courant.

Mais je suis frustré parce que je ne vois pas ce qui ne marche pas dans la regex. A moins que ce soit le "|" qui ne marche pas comme on veut. Peut être que lorsqu'on n'entre pas dans la première condition parce qu'on est entre des balises html et bien il va voir si la deuxième condition peut être vérifiée. Ici ca sera toujours le cas puisque la 2eme condition correspond au mot tout seul.

Peut être qu'il ne faut pas passer par un "|". Je vais faire mes propres recherches je te tiens au courant.
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 14:56
ce que je veux dire, c'est simple :

le Replace n'est pas la seule chose que te permettent les regexp.

tu peux itérer sur chacun des elements trouvés, et faire ce replace par toi même, à la main.
tu as juste a tester l'element trouvé, pour ignorer les balises HTML dans les resultats remontés par la regexp.


une autre solution plus simple est de faire cela par étapes :

toujours avec:
(<[^>]*?handicap.*?>|handicap)

tu remplaces par exemple par :
{$1} (va ajouter des accolades { } autour des resultats trouvés

au resultat obtenu par replace, tu fais :
\{(<[^>]*?>)\}
avec $1 pour remplacer (supprime les accolades autour des balises HTML)

enfin, utiliser:
\{(.*?)\}
et pour replace:
$1


et hop

c'est par étapes, certes, mais bon.... ca fonctionne ^^

Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 15:01
par étapes, en VB on aura:
Dim sBuffer As String
    With New RegExp
        .Global = True
        .IgnoreCase = True
        sBuffer = "handicap handicap sur handicap handicap handicap"
        
        .Pattern = "(<[^>]*?handicap.*?>|handicap)"
        sBuffer = .Replace(sBuffer, "{{$1}}")
        
        .Pattern = "\{\{(<[^>]*?>)\}\}"
        sBuffer = .Replace(sBuffer, "$1")
        
        .Pattern = "\{\{(.*?)\}\}"
        sBuffer = .Replace(sBuffer, "$1")
        
        MsgBox sBuffer
    End With



Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 15:13
et en traitement manuel, toujours en VB:
Dim sBuffer As String
Dim sOut As String
Dim nPos As Long
Dim oMatch As Match
    With New RegExp
        .Global = True
        .IgnoreCase = True
        sBuffer = "hello handicap handicap sur handicap handicap handicap"
        
        .Pattern = "(<[^>]*?handicap.*?>|handicap)"
        
        For Each oMatch In .Execute(sBuffer)
            sOut = sOut & Mid$(sBuffer, nPos + 1, oMatch.FirstIndex - nPos)
            nPos = oMatch.FirstIndex + oMatch.Length
            If Left$(oMatch.Value, 1) = "<" Then
                sOut = sOut & oMatch.Value
            Else
                sOut = sOut & "" & oMatch.Value & ""
            End If
        Next
        
        MsgBox sOut
    End With



Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
22 juil. 2009 à 17:00
Alors là...
J'ai essayé de rentrer tous les mots possibles, toutes les balises possibles... Je dois avouer que ton code est infaillible !!

C'est trop bien ! Tu es mon sauveur

Y'a quand même un truc que j'aimerais que tu m'expliques : ta regex !
Oui je suis perdu là !
Il me semble que tu utilises le lookahead "?!" alors que en même temps tu utilises une classe négative "[^<]". Il me semblait que c'était soit l'un soit l'autre, que le lookahead était là pour palier à un manque par rapport aux classes négatives.

J'ai regardé la description de ton outil et les commentaires ca a l'air sympa. J'aurai plus d'excuses pour ne pas essayer les regex par moi-même !!
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
22 juil. 2009 à 20:21
handicap(?![^<]*?>)

handicap, si pas suivi de 0 à n caractères (sauf ouverture de balise) et au final une fermeture de balise.


Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
22 juil. 2009 à 21:48
Je comprends toujours pas !
handicap, si pas suivi de 0 à n caractères

Mais pas suivi par quoi ? Car ce qui vient juste apres, "[^<]", ca n'indique pas par quoi ca ne peut pas être suivi mais plutôt ce par quoi ca peut etre suivi, non ?
handicap(?![^<]*?>)
J'ai l'impression que ce qui est en rouge indique que ca ne peut pas être suivi par ce qui est en vert (à l'autre bout de la regex donc !!)

C'est bizarre cette double négation dans "?![^<]".Ca veut bien dire que le mot handicap peut être suivi par "<" mais c'est pas obligé??

Je chauffe ?

Excuse moi de te sortir mes pensées "en vrac" mais qu'est-ce que ca me ferait plaisir si je pouvais comprendre !
...
0
cs_romain117 Messages postés 53 Date d'inscription lundi 29 juin 2009 Statut Membre Dernière intervention 21 juillet 2013 1
22 juil. 2009 à 22:56
Miracle : j'ai compris !!
En fait j'avais pas fait gaffe que "?!" c'était pour toute l'expression entre parenthèses. C'est beaucoup plus clair maintenant !!


Un grand grand (grand) MERCI à toi Renfield.

Sans me risquer je peux dire que le sujet est DEFINITIVEMENT RESOLU (je cherche encore une faille mais non j'en trouve pas !!)

J'espère que t'es payé pour donner de l'aide parce que rien que pour m'aider je suis sûr que tu as dû y passer un certain temps.

Chapeau !

A la prochaine

Romain
0
Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
23 juil. 2009 à 01:05
payé ? oui, j'acquiert des connaissances ^^

Renfield - Admin CodeS-SourceS - MVP Visual Basic
0
Rejoignez-nous