problème de regex de détection des #

Mammouth du PHP | 843 Messages

14 déc. 2007, 15:40

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 ;)
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

14 déc. 2007, 16:50

Pas pu tester, mais le premier truc qui me viendrait en tête c'est ça :

Code : Tout sélectionner

/([^&](#+)|(&&#+))/
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Mammouth du PHP | 505 Messages

14 déc. 2007, 18:18

Avec des assertions, ca a l'air de passer

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

Mammouth du PHP | 843 Messages

14 déc. 2007, 19:28

@ 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 ;)
:?
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Mammouth du PHP | 505 Messages

15 déc. 2007, 10:45

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 :)

Mammouth du PHP | 843 Messages

15 déc. 2007, 13:05

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 < ?
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Mammouth du PHP | 505 Messages

15 déc. 2007, 13:11

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,}§
Modifié en dernier par titerm le 15 déc. 2007, 15:34, modifié 1 fois.

Mammouth du PHP | 843 Messages

15 déc. 2007, 13:22

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 :)
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Mammouth du PHP | 505 Messages

15 déc. 2007, 14:47

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... :)

ViPHP
ViPHP | 4039 Messages

15 déc. 2007, 14:51

ç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..
Mais qu'importe. (je suis ici - dernier petit projet)
Berze going social.

Mammouth du PHP | 505 Messages

15 déc. 2007, 15:07

Voila une base que tu peux compléter

Code : Tout sélectionner

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

Mammouth du PHP | 843 Messages

15 déc. 2007, 19:06

@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 ;)
Modifié en dernier par BeRoots le 15 déc. 2007, 19:14, modifié 1 fois.
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

Mammouth du PHP | 505 Messages

15 déc. 2007, 19:14

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.

Mammouth du PHP | 843 Messages

15 déc. 2007, 19:28

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 ;)
:: contactez moi par MP ::
:non: NON au language SMS sur les forums :non:

ViPHP
ViPHP | 4674 Messages

15 déc. 2007, 20:10

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 !
« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

Hoa : http://hoa-project.net (sur @hoaproject).