Vous faites correspondre des caractères , pas des séquences de caractères . Fondamentalement, vous correspondez à 0, 1 à 1 et 2 (c'est-à-dire 0, 1 et 2). Considérez ceci:, cela [a-z0-9]correspond à toutes les lettres minuscules et à tous les chiffres, mais uniquement comme un seul caractère.
0 [1-9] | 1 [0-2] -> 0 | 1 | 2 -> [] s dans une expression régulière désignent une classe de caractères. Si aucune plage n'est spécifiée, il ors implicitement chaque caractère.
Badri Gs
Avez-vous besoin de le faire correspondre avec une regex pure? Sinon, vous pouvez: 1.) simplement utiliser le \d+modèle, 2.) convertir les chaînes correspondantes en nombres dans votre code. puis, 3.) vérifiez la plage de numéros comme if(num >= 0 && num <= 12){ /*do something*/ }. C'est tellement plus rapide et flexible.
acegs
Réponses:
192
Vous semblez avoir mal compris comment la définition des classes de caractères fonctionne dans les regex.
Pour correspondre à l' une des chaînes 01, 02, 03, 04, 05, 06, 07, 08, 09, 10, 11, ou 12, quelque chose comme ça fonctionne:
Plages numériques (ont de nombreux exemples sur les chaînes correspondantes interprétées comme des plages numériques)
Explication
Une classe de caractères, par elle-même, tente de faire correspondre un et exactement un caractère de la chaîne d'entrée. [01-12]définit en fait [012], une classe de caractères qui correspond à un caractère de l'entrée contre l' un des 3 caractères 0, 1ou 2.
La -définition de la plage va de 1à 1, ce qui inclut juste 1. D'autre part, quelque chose comme [1-9]inclut 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 "fonctionne" pas. Cette définition caractère définit [this|a], à savoir qu'il correspond à un caractère de l'entrée contre l' un des 6 caractères t, h, i, s, |ou a. Ce (this|that)qui est prévu est plus que probable .
Il est donc évident maintenant qu'un modèle comme between [24-48] hoursne "fonctionne" pas. La classe de caractères dans ce cas est équivalente à [248].
Autrement dit, -dans une définition de classe de caractères, ne définit pas de plage numérique dans le modèle. Les moteurs Regex ne «comprennent» pas vraiment les nombres dans le modèle, à l'exception de la syntaxe de répétition finie (par exemple, les a{3,5}correspondances entre 3 et 5 a).
La définition de plage utilise à la place le codage ASCII / Unicode des caractères pour définir les plages. Le caractère 0est codé en ASCII en décimal 48; 9est 57. Ainsi, la définition de caractère [0-9]inclut tous les caractères dont les valeurs sont comprises entre la décimale 48 et 57 dans le codage. Plutôt sensiblement, par la conception ce sont les personnages 0, 1..., 9.
Pour moi, je cherchais des mois sans préfixer avec 0 si un seul chiffre. Et j'ai utilisé ceci ([1-9] | (1 [0-2])) et ça marche.
bunjeeb
2
Important à noter: si vous trouvez que cette page souhaite une solution pour votre plage de numéros qui ne comporte que des chiffres uniques avant d'arriver aux dizaines, 0[1-9]|1[0-2]cela ne fonctionnera pas. Changement à l'étape suivante logique [1-9]|1[0-2]ne fonctionne pas non plus pour des raisons compréhensibles (elle correspond à la 1seule dans 10, 11et 12). J'ai dû utiliser \b(?:[0-9]|1[0-1])\bpour éviter cela. \bs s'assure que l'expression régulière correspond aux limites des mots (ou dans ce cas, des nombres) ( ^& $non); les parenthèses font que ou ( |) considère l'autre côté de celui-ci; et enfin ?:est de ne pas créer de sous-correspondance avec l'utilisation des crochets.
user66001
@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 expression régulière JS correspond à plus de 17?
edam
@edam - polygenelubricants pourraient, et ainsi pourrais - je, mais nous serions répondent un questi ... attente ... est - ce une question que vous posez dans un commentaire ? Il y a des règles sur ce site;) Posez une question si vous avez une nouvelle question. Les commentaires sont uniquement destinés à critiquer et à demander des éclaircissements, et à y répondre.
robinCTS
1
@edam Oh, je vois. Vous avez re-demander comme une question d' une heure plus tard. C'est génial! Cependant, ce serait probablement une bonne idée de supprimer votre commentaire ici.
robinCTS
24
Une classe de caractères dans les expressions régulières, désignée par la [...]syntaxe, spécifie les règles pour faire correspondre 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 patron, [01-12]se décompose donc comme suit:
0 - correspond au chiffre unique 0
ou, 1-1, correspond à un seul chiffre compris entre 1 et 1
ou, 2, correspond à un seul chiffre 2
Donc, fondamentalement, tout ce que vous correspondez est 0, 1 ou 2.
Afin de faire la correspondance que vous voulez, en faisant correspondre deux chiffres, allant de 01 à 12 sous forme de nombres, vous devez réfléchir à leur apparence sous forme de texte.
Tu as:
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 by1-9||+-- a 1 followed by0-2||<-+--><-+-->0[1-9]|1[0-2]^|+-- vertical bar,this roughly means "OR"inthis context
Notez qu'essayer de les combiner afin d'obtenir une expression plus courte échouera, en donnant des correspondances fausses positives pour une entrée invalide.
Par exemple, le modèle [0-1][0-9]correspondrait essentiellement aux nombres 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 caractères, mais pour l'instant, tout ce que je peux vous donner est cette requête Google pour les classes de caractères Regex . J'espère que vous pourrez y trouver plus d'informations pour vous aider.
Pour être exact, [0-1][0-2]correspond également 00. Cela dit, +1 pour le lien (que j'ai utilisé dans ma réponse).
polygenelubricants
2
[0-1][0-2]doivent être interprétées avec prudence, car elle permet chaînes comme 00, 01et 02, mais il ne reconnaît pas 03jusqu'à 09, enfin admettre 10, 11et 12. Une bonne expression régulière pour cela est [1-9]|1[0-2], ou même 0*([1-9]|1[0-2])(ce dernier autorisant n'importe quel nombre de zéros non significatifs).
Luis Colorado
1
Le []s dans une expression régulière dénote une classe de caractères . Si aucune plage n'est spécifiée, il est implicitement ou s tous les caractères qu'il contient ensemble. Ainsi, [abcde]est le même que (a|b|c|d|e), sauf qu'il ne capture rien; il correspondra à une des a, b, c, dou e. Tout ce qu'une plage indique est un ensemble de caractères ; [ac-eg]dit "correspond à l'un des caractères suivants a:; tout caractère entre cet e; ou g". Ainsi, votre correspondance dit "correspond à l'un des caractères suivants 0:; tout caractère entre 1et 1( c'est -à- dire juste 1); ou 2.
Votre objectif est évidemment de spécifier une plage de nombres: n'importe quel nombre entre 01et 12écrit avec deux chiffres. Dans ce cas précis, vous pouvez le faire correspondre avec 0[1-9]|1[0-2]: soit a 0suivi de n'importe quel chiffre entre 1et 9, soit a 1suivi de n'importe quel chiffre entre 0et 2. En général, vous pouvez transformer n'importe quelle plage de nombres en une expression régulière valide de la même manière. Il peut y avoir une meilleure option que les expressions régulières, cependant, ou une fonction ou un module existant qui peut construire l'expression régulière pour vous. Cela dépend de votre langue.
Comme le dit polygenelubricants, le vôtre recherchera 0 | 1-1 | 2 plutôt que ce que vous souhaitez, car les classes de caractères (les éléments entre []) correspondent à des caractères plutôt qu'à des chaînes.
[a-z0-9]
correspond à toutes les lettres minuscules et à tous les chiffres, mais uniquement comme un seul caractère.\d+
modèle, 2.) convertir les chaînes correspondantes en nombres dans votre code. puis, 3.) vérifiez la plage de numéros commeif(num >= 0 && num <= 12){ /*do something*/ }
. C'est tellement plus rapide et flexible.Réponses:
Vous semblez avoir mal compris comment la définition des classes de caractères fonctionne dans les regex.
Pour correspondre à l' une des chaînes
01
,02
,03
,04
,05
,06
,07
,08
,09
,10
,11
, ou12
, quelque chose comme ça fonctionne:Références
Explication
Une classe de caractères, par elle-même, tente de faire correspondre un et exactement un caractère de la chaîne d'entrée.
[01-12]
définit en fait[012]
, une classe de caractères qui correspond à un caractère de l'entrée contre l' un des 3 caractères0
,1
ou2
.La
-
définition de la plage va de1
à1
, ce qui inclut juste1
. D'autre part, quelque chose comme[1-9]
inclut1
,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 "fonctionne" pas. Cette définition caractère définit[this|a]
, à savoir qu'il correspond à un caractère de l'entrée contre l' un des 6 caractèrest
,h
,i
,s
,|
oua
. Ce(this|that)
qui est prévu est plus que probable .Références
Comment les plages sont définies
Il est donc é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]
.Autrement dit,
-
dans une définition de classe de caractères, ne définit pas de plage numérique dans le modèle. Les moteurs Regex ne «comprennent» pas vraiment les nombres dans le modèle, à l'exception de la syntaxe de répétition finie (par exemple, lesa{3,5}
correspondances entre 3 et 5a
).La définition de plage utilise à la place le codage ASCII / Unicode des caractères pour définir les plages. Le caractère
0
est codé en ASCII en décimal 48;9
est 57. Ainsi, la définition de caractère[0-9]
inclut tous les caractères dont les valeurs sont comprises entre la décimale 48 et 57 dans le codage. Plutôt sensiblement, par la conception ce sont les personnages0
,1
...,9
.Voir également
Un autre exemple: de A à Z
Jetons un coup d'œil à une autre définition de classe de caractères commune
[a-zA-Z]
En ASCII:
A
= 65,Z
= 90a
= 97,z
= 122Cela signifie que:
[a-zA-Z]
et[A-Za-z]
sont équivalents[a-Z]
s'agit probablement d'une plage de caractères illégalea
(97) est "supérieur à" queZ
(90)[A-z]
est légal, mais comprend également ces six caractères:[
(91),\
(92),]
(93),^
(94),_
(95),`
(96)Questions connexes
la source
0[1-9]|1[0-2]
cela ne fonctionnera pas. Changement à l'étape suivante logique[1-9]|1[0-2]
ne fonctionne pas non plus pour des raisons compréhensibles (elle correspond à la1
seule dans10
,11
et12
). J'ai dû utiliser\b(?:[0-9]|1[0-1])\b
pour éviter cela.\b
s s'assure que l'expression régulière correspond aux limites des mots (ou dans ce cas, des nombres) (^
&$
non); les parenthèses font que ou (|
) considère l'autre côté de celui-ci; et enfin?:
est de ne pas créer de sous-correspondance avec l'utilisation des crochets."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 expression régulière JS correspond à plus de 17?Une classe de caractères dans les expressions régulières, désignée par la
[...]
syntaxe, spécifie les règles pour faire correspondre 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 patron,
[01-12]
se décompose donc comme suit:Donc, fondamentalement, tout ce que vous correspondez est 0, 1 ou 2.
Afin de faire la correspondance que vous voulez, en faisant correspondre deux chiffres, allant de 01 à 12 sous forme de nombres, vous devez réfléchir à leur apparence sous forme de texte.
Tu as:
Vous devrez alors écrire une expression régulière pour cela, qui peut ressembler à ceci:
Notez qu'essayer de les combiner afin d'obtenir une expression plus courte échouera, en donnant des correspondances fausses positives pour une entrée invalide.
Par exemple, le modèle
[0-1][0-9]
correspondrait essentiellement aux nombres 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 caractères, mais pour l'instant, tout ce que je peux vous donner est cette requête Google pour les classes de caractères Regex . J'espère que vous pourrez y trouver plus d'informations pour vous aider.
la source
Cela fonctionne également:
^([1-9]|[0-1][0-2])$
[1-9]
correspond à des chiffres uniques entre 1 et 9[0-1][0-2]
correspond à deux chiffres entre 10 et 12Il y a quelques bons exemples ici
la source
[0-1][0-2]
correspond également00
. Cela dit, +1 pour le lien (que j'ai utilisé dans ma réponse).[0-1][0-2]
doivent être interprétées avec prudence, car elle permet chaînes comme00
,01
et02
, mais il ne reconnaît pas03
jusqu'à09
, enfin admettre10
,11
et12
. Une bonne expression régulière pour cela est[1-9]|1[0-2]
, ou même0*([1-9]|1[0-2])
(ce dernier autorisant n'importe quel nombre de zéros non significatifs).Le
[]
s dans une expression régulière dénote une classe de caractères . Si aucune plage n'est spécifiée, il est implicitement ou s tous les caractères qu'il contient ensemble. Ainsi,[abcde]
est le même que(a|b|c|d|e)
, sauf qu'il ne capture rien; il correspondra à une desa
,b
,c
,d
oue
. Tout ce qu'une plage indique est un ensemble de caractères ;[ac-eg]
dit "correspond à l'un des caractères suivantsa
:; tout caractère entrec
ete
; oug
". Ainsi, votre correspondance dit "correspond à l'un des caractères suivants0
:; tout caractère entre1
et1
( c'est -à- dire juste1
); ou2
.Votre objectif est évidemment de spécifier une plage de nombres: n'importe quel nombre entre
01
et12
écrit avec deux chiffres. Dans ce cas précis, vous pouvez le faire correspondre avec0[1-9]|1[0-2]
: soit a0
suivi de n'importe quel chiffre entre1
et9
, soit a1
suivi de n'importe quel chiffre entre0
et2
. En général, vous pouvez transformer n'importe quelle plage de nombres en une expression régulière valide de la même manière. Il peut y avoir une meilleure option que les expressions régulières, cependant, ou une fonction ou un module existant qui peut construire l'expression régulière pour vous. Cela dépend de votre langue.la source
Comme le dit polygenelubricants, le vôtre recherchera 0 | 1-1 | 2 plutôt que ce que vous souhaitez, car les classes de caractères (les éléments entre []) correspondent à des caractères plutôt qu'à des chaînes.
la source
0|1-1|2
- cette notation est très trompeuse. Quelque chose comme0|1|2
serait plus précis.Utilisez ceci:
Pour tester un modèle comme 07/2018, utilisez ceci:
(Plage de dates entre 01/2000 et 12/9999)
la source