122 votes

Pourquoi la gamme [01-12] ne fonctionne-t-elle pas comme prévu ?

J'essaie d'utiliser le modèle de gamme [01-12] dans l'expression rationnelle pour faire correspondre les mm à deux chiffres, mais cela ne fonctionne pas comme prévu.

10 votes

Vous correspondez caractères no séquences de caractères . Fondamentalement, vous êtes en correspondance avec 0, 1 à 1 et 2 (c'est-à-dire 0, 1 et 2). Considérez ceci : [a-z0-9] ce qui correspond à toutes les lettres minuscules et à tous les chiffres, mais uniquement sous la forme d'un seul caractère.

0 votes

Pour info, j'ai créé un outil javascript qui crée une regex hautement optimisée à partir de deux entrées (min/max). github.com/jonschlinkert/to-regex-range

0 votes

0[1-9]|1[0-2] -> 0|1|2 -> []s dans une regex dénotent une classe de caractères. Si aucune plage n'est spécifiée, la regex utilise implicitement tous les caractères.

255voto

polygenelubricants Points 136838

Vous semblez avoir mal compris le fonctionnement de la définition des classes de caractères dans les regex.

Pour correspondre à l'une des chaînes de caractères 01 , 02 , 03 , 04 , 05 , 06 , 07 , 08 , 09 , 10 , 11 o 12 quelque chose comme ça fonctionne :

0[1-9]|1[0-2]

Références


Explication

Une classe de caractères, par elle-même, tente de correspondre à un et exactement un de la chaîne de caractères d'entrée. [01-12] définit en fait [012] une classe de caractères qui fait correspondre un caractère de l'entrée à l'un des trois caractères. 0 , 1 o 2 .

El - La définition de la gamme va de 1 à 1 qui comprend seulement 1 . D'autre part, quelque chose comme [1-9] incluye 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 .

Les débutants font souvent l'erreur de définir des choses comme [this|that] . Cela ne "marche" pas. Cette définition de caractère définit [this|a] c'est-à-dire qu'il fait correspondre un caractère de l'entrée à l'un des 6 caractères de la base de données. t , h , i , s , | o a . Plus que probable (this|that) est ce qui est prévu.

Références


Comment les gammes sont définies

Donc il est évident maintenant qu'un modèle comme between [24-48] hours ne "fonctionne" pas. La classe de caractères dans ce cas est équivalente à [248] .

C'est-à-dire, - dans une définition de classe de caractères ne définit pas de plage numérique dans le motif. Les moteurs de regex ne "comprennent" pas vraiment les nombres dans le motif, à l'exception de la syntaxe de répétition finie (par ex. a{3,5} matches entre 3 et 5 a ).

La définition des plages utilise plutôt l'encodage ASCII/Unicode des caractères pour définir les plages. Le caractère 0 est codé en ASCII en décimal 48 ; 9 a 57 ans. Ainsi, la définition du caractère [0-9] inclut tous les caractères dont les valeurs sont comprises entre les décimales 48 et 57 dans l'encodage. De manière plutôt sensée, par conception, ce sont les caractères suivants 0 , 1 , ..., 9 .

Voir aussi


Un autre exemple : De A à Z

Examinons la définition d'une autre classe de caractères courante. [a-zA-Z]

En ASCII :

  • A = 65, Z = 90
  • a = 97, z = 122

Cela signifie que :

  • [a-zA-Z] y [A-Za-z] sont équivalentes
  • Dans la plupart des parfums, [a-Z] est susceptible d'être une plage de caractères illégale
    • parce que a (97) est "plus grand que" que Z (90)
  • [A-z] est légal, mais comprend également ces six caractères :
    • [ (91), \ (92), ] (93), ^ (94), _ (95), ` (96)

Questions connexes

0 votes

Pour moi, je cherchais des mois sans préfixe avec 0 si un seul chiffre. Et j'ai utilisé ceci ([1-9]|(1[0-2])) et ça marche.

4 votes

Il est important de noter : Si vous trouvez cette page en cherchant une solution pour votre série de chiffres qui n'a que des chiffres simples avant d'arriver aux dizaines, 0[1-9]|1[0-2] ne fonctionnera pas. Passer à l'étape suivante logique [1-9]|1[0-2] ne fonctionne pas non plus pour des raisons compréhensibles (il correspond à l'option 1 seulement en 10 , 11 y 12 ). J'ai dû utiliser \b(?:[0-9]|1[0-1])\b pour empêcher cela. \b s'assure que l'expression correspond aux limites des mots (ou dans ce cas des nombres) ( ^ & $ ne l'a pas fait) ; les parenthèses rendent le ou ( | ) considérer l'autre côté de la médaille ; et enfin ?: est de ne pas créer un sous-match avec l'utilisation des parenthèses.

0 votes

@polygenelubricants : "1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g ) Pouvez-vous me dire pourquoi cette regex JS correspond à plus de 17 ?

29voto

Lasse V. Karlsen Points 148037

Une classe de caractères dans les expressions régulières, désignée par le symbole [...] syntaxe, spécifie les règles de correspondance un seul caractère dans l'entrée. En tant que tel, tout ce que vous écrivez entre les crochets spécifie comment faire correspondre un seul caractère .

Votre modèle, [01-12] se décompose donc comme suit :

  • 0 - correspond au chiffre unique 0
  • ou, 1-1, correspond à un seul chiffre dans la plage de 1 à 1
  • ou, 2, correspond à un chiffre unique 2

Donc, en gros, tout ce que vous avez à faire est 0, 1 ou 2.

Pour obtenir la correspondance que vous souhaitez, c'est-à-dire faire correspondre deux chiffres, allant de 01 à 12, en tant que nombres, vous devez réfléchir à la façon dont ils se présenteront en tant que texte.

Vous avez :

  • 01-09 (c'est-à-dire que le premier chiffre est 0, le deuxième chiffre est 1-9)
  • 10-12 (c'est-à-dire que le premier chiffre est 1, le deuxième chiffre est 0-2)

Vous devrez alors écrire une expression régulière pour cela, qui peut ressembler à ceci :

  +-- a 0 followed by 1-9
  |
  |      +-- a 1 followed by 0-2
  |      |
<-+--> <-+-->
0[1-9]|1[0-2]
      ^
      |
      +-- vertical bar, this roughly means "OR" in this context

Notez que si vous essayez de les combiner afin d'obtenir une expression plus courte, vous échouerez, car vous obtiendrez de fausses correspondances positives pour des entrées invalides.

Par exemple, le modèle [0-1][0-9] correspondrait essentiellement aux numéros 00-19, ce qui est un peu plus que ce que vous voulez.

J'ai essayé de trouver une source précise pour plus d'informations sur les classes de personnages, mais pour l'instant tout ce que je peux vous donner est ceci Recherche de classes de caractères Regex sur Google . J'espère que vous y trouverez des informations supplémentaires pour vous aider.

10voto

Barry Points 18913

Cela fonctionne aussi :

^([1-9]|[0-1][0-2])$

[1-9] correspond à des chiffres simples compris entre 1 et 9

[0-1][0-2] correspond à des chiffres doubles entre 10 et 12

Il existe quelques bons exemples ici

3 votes

Pour être exact, [0-1][0-2] correspond également à 00 . Cela dit, +1 pour le lien (que j'ai utilisé dans ma réponse).

2 votes

[0-1][0-2] doit être interprété avec précaution, car il autorise des chaînes de caractères telles que 00 , 01 y 02 mais il n'admet pas 03 jusqu'à 09 en admettant finalement 10 , 11 y 12 . Une bonne expression rationnelle pour cela est [1-9]|1[0-2] ou encore 0*([1-9]|1[0-2]) (ce dernier permettant un nombre quelconque de zéros de tête).

1voto

Antal S-Z Points 17977

El [] dans une regex désignent une classe de caractères . Si aucune fourchette n'est spécifiée, la méthode est implicite. ou tous les personnages qui la composent. Ainsi, [abcde] est la même chose que (a|b|c|d|e) sauf qu'il ne capture rien ; il correspondra à n'importe quel des éléments suivants a , b , c , d o e . Tout ce qu'une gamme indique est un ensemble de caractères ; [ac-eg] dit "correspond à l'un des éléments suivants : a ; tout caractère entre c y e ; ou g ". Ainsi, votre correspondance dit "correspond à l'un des éléments suivants : 0 ; tout caractère entre 1 y 1 ( c'est-à-dire juste 1 ) ; ou 2 .

Votre objectif est évidemment de spécifier une plage de nombres : tout nombre compris entre 01 y 12 écrit avec deux chiffres. Dans ce cas spécifique, vous pouvez le faire correspondre avec 0[1-9]|1[0-2] : soit a 0 suivi de tout chiffre compris entre 1 y 9 ou un 1 suivi de tout chiffre compris entre 0 y 2 . En général, vous pouvez transformer n'importe quelle plage de nombres en une expression régulière valide de manière similaire. Cependant, il existe peut-être une meilleure option que les expressions régulières, ou une fonction ou un module existant qui peut construire l'expression rationnelle pour vous. Cela dépend de votre langue.

1voto

Eolia Points 49

Utilisez ça :

0?[1-9]|1[012]
  • 07 : valide
  • 7 : valide
  • 0 : pas de correspondance
  • 00 : pas de correspondance
  • 13 : ne correspond pas
  • 21 : ne correspond pas

Pour tester un modèle comme 07/2018, utilisez ceci :

/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/

(Date comprise entre 01/2000 et 12/9999)

0 votes

J'ai essayé de comprendre comment faire cela, mais pour que la troisième condition de seulement un 0 passe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X