Page 1 sur 2

problème de regex de détection des #

Posté : 14 déc. 2007, 15:40
par BeRoots
salut à tous :)
j'aimerai faire une regexp qui me capture uniquement les # d'un contenu avec pour conditions, que celle-ci ne soit pas préceder d'un & (comme { par exemple) et que l'on détecte aussi le cas &&# :-k
en gros pour du texte comme suit, en vert les detextion et en rouge les cas à ne pas détecter:
un p'tit texte plein de # détectable pour dire que # est détecter et que { ne le sera pas.
Il faudra aussi détecter le cas particulier &&# ainsi que les suite de ######## ou autre &##### sans pour autant que le pattern ne s'étende sur les catactères pouvant aussi préceder les dite###### et [ceci est un espace]#
cela fait plus de 24h que je cherche dessus et j'en suit ici:
!((&&+|[^&])#+)!
En gros, il ne me détecte pas les &# et il me détecte bien les &&# ainsi que toutes les # et ####.
mon soucit et que ce pattern sélectionne tout caractère autre que & lorsque &# n'est pas reconnu...

si quelqu'un à une idée pour faire en sorte que le pattern ne déborde pas si un autre caractère (même blanc) que le & unique est présent devant la # ?

merci d'avance de votre aide ;)

Posté : 14 déc. 2007, 16:50
par Ryle
Pas pu tester, mais le premier truc qui me viendrait en tête c'est ça :

Code : Tout sélectionner

/([^&](#+)|(&&#+))/

Posté : 14 déc. 2007, 18:18
par titerm
Avec des assertions, ca a l'air de passer

(?<!&)#|(?<=&&)#|(?<=&)#{2,}

Posté : 14 déc. 2007, 19:28
par BeRoots
@ Ryle: merçi j'avais déja essayer mais sans succes :?

@ Titerm: Jackpot :lol: merci, je connaissait pas encore les assertions et je m'en vait d'ailleur de ce pas voir dans la doc pour en apprendre d'avantage :)

au cas où cela puisse reservir, j'ai un peu modifier pour détecter complètement le &&# :

§(?<!&)#|&&#|(?<=&)#{2,}§

encore merci à vous deux :D

encore une petite question en ce qui concerne le même problème ou presque mais avec les // sachant que je veut sélectionné tout ce qui est /{2,} et ne pas sélectionné les symbole / :// et :///
voici ce que j'ai fait:

Code : Tout sélectionner

§(?<!:)///|(?<!:)//§
tout fonctionne mais mon seul manque est que je sélectionne encores les // dans les chaines du style file:///c:/php/pnp.ini (du faite que j'ai un :/ devant un // :-k

j'ai essayer pas mal de chose mais rien à faire

si quelqu'un à une idée ;)
:?

Posté : 15 déc. 2007, 10:45
par titerm
Tu y était presque...

Code : Tout sélectionner

!(?<!:/?)/{2,}!
Quand aux assertions... C'est extrêmement vaste...
Moi, ca fait 20ans que je fais des regexp et je découvre encore régulièrement des trucs que je connaissais pas ou qui ont évolués avec les nouveaux moteurs... Alors don't worry :)

Posté : 15 déc. 2007, 13:05
par BeRoots
j'ai bien essayer ce que tu m'a dit mais pas moyen :?
1 (preg_match_all) : !(?<!:/?)/{2,}!
2/117 preg_match_all() [function.preg-match-all]: Unknown modifier ':'
j'ai donc essayer ceci au cas ou cela vienne des "séparateur"

Code : Tout sélectionner

§(?<!:/?)/{2,}§
j'ai plus le même message mais c'est toujour pas ça...
1 (preg_match_all) : §(?<!:/?)/{2,}§
2/117 preg_match_all() [function.preg-match-all]: Compilation failed: lookbehind assertion is not fixed length at offset 7
1°) si quelqu'un à une idée ?

j'aimerai aussi interdire la sélection de balise html en fin de chaine pour une détection d'url.
j'ai cette regex mais j'aimerai que celle-ci s'arrete avant les < pourvant ce trouver à la suite de l'url :-k
§(((file|ed2k|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://)|(file:///)|(www\.))+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[-a-zA-Z0-9&+=?#%_\./~]*)?§
voila la sélection que celle si me retourne:
2°) si quelqu'un à une idée sur comment arrêter la sélection avant le < ?

Posté : 15 déc. 2007, 13:11
par titerm
uhmmm j'ai pas de php sous la main, pe un pb dans le moteur pcre de php...

essai avec des assertions à longueur fixe

Code : Tout sélectionner

§(?<!:|:/)/{2,}§

Posté : 15 déc. 2007, 13:22
par BeRoots
ok c'était bein ça :)

PS. pense à mettre entre balise code tes regex histoire d'éviver les smileys :lol:

Code : Tout sélectionner

§(?<!:|:/)/{2,}§
Par contre si quelqu'un à une idée ou une méthode sur mon problème de non détection des <br /> en fin d'url ;)

merci d'avance :)

Posté : 15 déc. 2007, 14:47
par titerm
Ah oui, désolé pour les smileys... Je regarderais ton dernier pb plus tard, la ma fille me tanne pour les déco de noël... :)

Posté : 15 déc. 2007, 14:51
par Berzemus
ça doit être si compliqué que ça le regex d'url ?

En toute vitesse, je trouve ceci: (sous peine que l'url débute avec http://)

Code : Tout sélectionner

http:[A-Za-z0-9/.?=&%+:]+
mais y'a de quoi améliorer..

Posté : 15 déc. 2007, 15:07
par titerm
Voila une base que tu peux compléter

Code : Tout sélectionner

\b(https?|ftp|file)://[-\w+&@#/%?=~_|!:,.;]*[-\w+&@#/%=~_|]

Posté : 15 déc. 2007, 19:06
par BeRoots
@Berzemus: refert toi au RCF822 et autes... pour voir ce qu'il en retourne point de vue normalisation des url ;)

@Titerm: pourquoi n'antislashe tu pas le . dans ta classe?

pour ce qui est de la non capture de mes balises html lors de la détection d'url, je ne m'explique toujour pas pourquoi ma regex capture celle-ci :-k
§(((file|ed2k|gopher|news|nntp|telnet|http|ftp|https|ftps|sftp)://)|(file:///)|(www\.))+(([a-zA-Z0-9\._-]+\.[a-zA-Z]{2,6})|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}))(/[-a-zA-Z0-9&+@=?#/%_|!:,.;~]*)?§
pourtant ma classe de catractère ne contient pas le < donc il ne devrai pas être détecter nan?
[-a-zA-Z0-9&+@=?#/%_|!:,.;~]

si quelqu'un à une idée ;)

Posté : 15 déc. 2007, 19:14
par titerm
Après test, ta reg ne capture pas plus loin que le y de azerty dans ton exemple :

Code : Tout sélectionner

http://www.domaine.fr/dossier/fichier.php?qq=1&qq2=e%20+e:azerty<br />
Soit tu tombes sur un bug du moteur pcre de php, soit, tu utilises encore un formulaire aproximatif pour l'évaluation de tes regexp... :), mais la reg, bien que complexe (trop ? ) capture l'url uniquement.

Posté : 15 déc. 2007, 19:28
par BeRoots
disons qu'elle est complexe mais elle me capture tout type d'url ou presque (www.domaine.fr ; http://127.0.0.1 ; file:///proram~01/fichier.tif et bien plus encore) :)

je viens de la modifier un peu pour prendre aussi les url de type ftp://user1:[email protected] :p
@Titerm: pourquoi n'antislashe tu pas le . dans ta classe?
\b(https?|ftp|file)://[-\w+&@#/%?=~_|!:,.;]*[-\w+&@#/%=~_|]

et aussi, voit tu des simplifications à apporter à cette regex pour une même détection de tout type d'url
si quelqu'un peut aussi me dire si il connait d'autre protocole genre htp ftp... qui ne serai pas enoncer dans cette regex ;)

sinon, je vais refaire une flopper de test en local pour voir ;)

Posté : 15 déc. 2007, 20:10
par Hywan
Parser une URL n'est pas si compliqué que ça. Il suffit de lire les RFCs. Plus particulièrement, la numéro 2396 et 3986.
Elle nous dit entre autre, que la forme d'une URL (ou URI ; mieux) est :

Code : Tout sélectionner

URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
On peut alors appliquer la regex de la RFC :

Code : Tout sélectionner

Regex 1 : #^(?:([^:/?\#]+):)?(?://([^/?\#]*))?([^?\#]*)(?:\?([^\#]*))?(?:\#(.*))?#
On l'applique sur :

Code : Tout sélectionner

scheme://authority/path/to/file.php?query=value#fragment
Avec ces expressions régulières, on récupère le scheme, l'authority, le path, la query, et le fragment (le procole, le nom de domaine, le chemin, la requête, et l'ancre).
Après, on peut appliquer une décomposition additionnelle avec la regex suivante sur l'authority, qui est de la forme : L'expression est :

Code : Tout sélectionner

Regex 2: #^(?:([^:@]+):([^@]+)@)?([^:]+)(?::(.*))?$#
On pourra alors récupérer le nom d'utilisateur, le mot de passe, l'authority plus précis, et le port.

Si tu veux tester toutes les parties de l'URI, jette un oeil à la partie Appendix A. Collected (A)BNF for URI. Il faut faire en gros 15 autres regex qui se recoupent les unes les autres. Je ne mets le code ici pour ne pas alourdir, surtout que tout se trouve dans les RFCs. Il faut regarder les types alpha, digit, alphabum, mark, gen-delims, sub-delims, reserved, unreserved, pct-encoded, uric, pchar, segment, segment-nz, path-absolute, et reg-name. Rien que ça, oui Monsieur. La plupart se recoupe, ou se recompose, heureusement.

J'ai fais une classe qui gère la validité d'une URI, mais ce sera avec mon framework. J'espère le sortir pour janvier 2008. Je peux néanmoins te fournir les codes avant :). Ou alors (et j'aimerais beaucoup) faire un tutorial pour PHPFrance sur la validation des URIs :).

Voilà, bonne lecture des RFCs !