Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

regexp, match

20 réponses
Avatar
Mihamina (R12y) Rakotomandimby
Bonjour,
Soient les morceaux de code suivants:
http://svn.infogerance.us/code/browser/JavaScriptCheckInput/trunk/index.html
http://svn.infogerance.us/code/browser/JavaScriptCheckInput/trunk/check_input.js

Ce que je cherche à faire avec est de faire un fomulaire avec un champ
texte et un submit mais ou le bouton submit disparait:
- quand un un caractère non autorisé est entré
- quand la chaine entrée contient un caractère non autorisé.

Je fais le controle de la chaine entrée à chaque evenement onKeyUp.
Je n'autausrise que les lettres majuscules et minuscules.

Le problème est que ce code fonctionne partiellement:
- le bouton submit disparait quand je rentre un espace mais réapparait
quand je rentre une lettre...
- ce n'est pas regulier, mais aléatoire.

Le navigateur avec lequel je teste: Firefox 2
Une chaine, entrée par caractère qui déclenche le bug: "ddd d d d d d d"

Merci pour tout eventuel coup de main.

10 réponses

1 2
Avatar
Mihamina (R12y) Rakotomandimby
Mihamina (R12y) Rakotomandimby wrote:

http://svn.infogerance.us/code/browser/JavaScriptCheckInput/trunk/check_input.js

Le navigateur avec lequel je teste: Firefox 2
Une chaine, entrée par caractère qui déclenche le bug: "ddd d d d d d d"


Si je fait
var expression = /[^a-z]/i;
au lieu de
var expression = /[^a-z]/gi;

Alors ça fonctionne.
Maintenant, je cherche à comprendre...

Avatar
Olivier Miakinen

http://svn.infogerance.us/code/browser/JavaScriptCheckInput/trunk/check_input.js

Le navigateur avec lequel je teste: Firefox 2
Une chaine, entrée par caractère qui déclenche le bug: "ddd d d d d d d"


Si je fait
var expression = /[^a-z]/i;
au lieu de
var expression = /[^a-z]/gi;

Alors ça fonctionne.
Maintenant, je cherche à comprendre...


Je n'ai pas la référence JavaScript près de moi, mais il me semble en
tout cas que si tu utilises exec() au lieu de test() le type du résultat
(tableau ou autre, peut-être une chaîne de caractères) dépend du nombre
de résultats trouvés. Alors transformer ce résultat en booléen comme tu
le fais me semble assez aléatoire avant de savoir ce qui doit réellement
être rendu.

Alors essaye de remplacer « if (resultat) » par « if (resultat.length) »
si tu es joueur, ou bien utilise test() à la place de exec(). Mais le
mieux serait quand même de lire une doc de référence.


Avatar
Mickaël Wolff
Si je fait
var expression = /[^a-z]/i;
au lieu de
var expression = /[^a-z]/gi;

Alors ça fonctionne.
Maintenant, je cherche à comprendre...


C'est parce que ta regexp ne contient pas les notions de début et de
fin d'expression, et qu'avec le taf global, il trouvait une portion de
la chaine testée qui correspondait à la regexp.

Pour être certain de tester toute la chaine, il faut indiquer que la
regexp contiennent les séquences de début (^) et de fin ($) de chaine :

/^[^a-z]$/i

/^[^a-z]$/i.exec('ddd') == null
/^[^a-z]$/i.exec('ddd ') == null
/^[^a-z]$/i.exec('ddd d') == null
/^[^a-z]$/i.exec(' ').length == 1

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Mickaël Wolff

Alors transformer ce résultat en booléen comme tu
le fais me semble assez aléatoire avant de savoir ce qui doit réellement
être rendu.


Ça renvoie un tableau ou null. Un tableau c'est toujours vrai, et
null, false. Donc il n'y a pas d'ambiguïté.

Mais c'est vrai que test, ce serait mieux. Ça optimiserais un chouia ;)

Alors essaye de remplacer « if (resultat) » par « if (resultat.length) »


Euh, non, puisqu'en cas de regex non vérifiée, Regexp.exec renvoie
null, et donc on risque de lever une exeception. Cf ma réponse qui a
télescopée la tienne.

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Olivier Miakinen

Alors transformer ce résultat en booléen comme tu
le fais me semble assez aléatoire avant de savoir ce qui doit réellement
être rendu.


Ça renvoie un tableau ou null. Un tableau c'est toujours vrai, et
null, false. Donc il n'y a pas d'ambiguïté.


S'il n'y a pas d'ambiguïté, alors comment expliquer le résultat obtenu
par Mihamina ?

Mais c'est vrai que test, ce serait mieux. Ça optimiserais un chouia ;)

Alors essaye de remplacer « if (resultat) » par « if (resultat.length) »


Euh, non, puisqu'en cas de regex non vérifiée, Regexp.exec renvoie
null, et donc on risque de lever une exeception.


D'accord avec ça. J'aurais mieux fait d'attendre de relire la doc avant
de sortir des bêtises.


Avatar
Olivier Miakinen

Si je fait
var expression = /[^a-z]/i;
au lieu de
var expression = /[^a-z]/gi;

Alors ça fonctionne.
Maintenant, je cherche à comprendre...


C'est parce que ta regexp ne contient pas les notions de début et de
fin d'expression, et qu'avec le taf global, il trouvait une portion de
la chaine testée qui correspondait à la regexp.


Ah non, je ne suis pas d'accord du tout.

Soit la chaîne "ddd d d d d d d".
/[^a-z]/i devrait donner array(" ")
/[^a-z]/gi devrait donner array(" ", " ", " ", " ", " ", " ")
Dans un cas comme dans l'autre, le tableau est non vide.

Je me trompe ?

Pour être certain de tester toute la chaine, il faut indiquer que la
regexp contiennent les séquences de début (^) et de fin ($) de chaine :

/^[^a-z]$/i


Ben non, ça ne peut pas fonctionner. Avec ce test, tu ne peux détecter
que les chaînes dont le *seul* caractère est autre chose qu'une lettre.

/^[^a-z]$/i.exec('ddd') == null


C'est bien, c'est ce qu'on veut.

/^[^a-z]$/i.exec('ddd ') == null
/^[^a-z]$/i.exec('ddd d') == null


Là c'est incorrect : on voudrait cacher le bouton Submit dans de tels cas.

/^[^a-z]$/i.exec(' ').length == 1


Ben oui, là il n'y a qu'un seul caractère.


Avatar
Mickaël Wolff

C'est parce que ta regexp ne contient pas les notions de début et de
fin d'expression, et qu'avec le taf global, il trouvait une portion de
la chaine testée qui correspondait à la regexp.


Ah non, je ne suis pas d'accord du tout.

Soit la chaîne "ddd d d d d d d".
/[^a-z]/i devrait donner array(" ")
/[^a-z]/gi devrait donner array(" ", " ", " ", " ", " ", " ")
Dans un cas comme dans l'autre, le tableau est non vide.

Je me trompe ?


Non, nous sommes d'accord.


Pour être certain de tester toute la chaine, il faut indiquer que la
regexp contiennent les séquences de début (^) et de fin ($) de chaine :

/^[^a-z]$/i


Ben non, ça ne peut pas fonctionner. Avec ce test, tu ne peux détecter
que les chaînes dont le *seul* caractère est autre chose qu'une lettre.


Pardon, je suis allé trop vite. Il fallait lire /^[^a-z]+$/i bien
évidemment. Merci d'avoir relevé ;) Mais en fait non, dans le cas
présent, ça ne va toujours pas. Parce que ça ne détecte que les chaines
composées de caractères interdits.

/^([^a-z]+|[a-z]*)+$/i devrait alors être utilisé si on veut être
certain de trouver au moins un caractère rejeté... mais c'est un peu
usine à gaz.

En fait, même sans utiliser le flag global ça aurait dû marcher...
Mihamina, est-ce que sans le flag global ta regexp continue à déconner
maintenant ?

Désolé d'avoir raconté des conneries, je lis trop vite les messages
auxquels je répond. Je vais aller cueillir des orties fraiches.

:)
--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org


Avatar
Mihamina (R12y) Rakotomandimby
Mickaël Wolff wrote:
Soit la chaîne "ddd d d d d d d".
/[^a-z]/i devrait donner array(" ")
/[^a-z]/gi devrait donner array(" ", " ", " ", " ", " ", " ")
Dans un cas comme dans l'autre, le tableau est non vide.
Je me trompe ?
Non, nous sommes d'accord.



Ok.

Pour être certain de tester toute la chaine, il faut indiquer que la
regexp contiennent les séquences de début (^) et de fin ($) de chaine :
/^[^a-z]$/i
Ben non, ça ne peut pas fonctionner. Avec ce test, tu ne peux détecter

que les chaînes dont le *seul* caractère est autre chose qu'une lettre.
Pardon, je suis allé trop vite. Il fallait lire /^[^a-z]+$/i bien

évidemment. Merci d'avoir relevé ;) Mais en fait non, dans le cas
présent, ça ne va toujours pas. Parce que ça ne détecte que les chaines
composées de caractères interdits.
/^([^a-z]+|[a-z]*)+$/i devrait alors être utilisé si on veut être
certain de trouver au moins un caractère rejeté... mais c'est un peu
usine à gaz.
En fait, même sans utiliser le flag global ça aurait dû marcher...
Mihamina, est-ce que sans le flag global ta regexp continue à déconner
maintenant ?


Sans le flag "g", ça marche bien.
Mais je ne comprends pas pourquoi. Je veux dire que je n'arrive pas à
formuler l'explication.



Avatar
Mickaël Wolff

Sans le flag "g", ça marche bien.
Mais je ne comprends pas pourquoi. Je veux dire que je n'arrive pas à
formuler l'explication.


Regarde le précédent post d'Olivier, il explique pourquoi. Mais au
fait, que signifie pour toi ce flag ?

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org

Avatar
Olivier Miakinen

Sans le flag "g", ça marche bien.
Mais je ne comprends pas pourquoi. Je veux dire que je n'arrive pas à
formuler l'explication.


Regarde le précédent post d'Olivier, il explique pourquoi.


Pas tout à fait. Je comprends très bien que cela fonctionne sans le flag
g, mais je ne vois pas du tout pourquoi ça ne marcherait pas avec.

Mais au fait, que signifie pour toi ce flag ?


Rechercher toutes les occurrences au lieu de s'arrêter à la première
trouvée.


1 2