À l'aide des expressions régulières pour valider une plage numérique
Mon nombre d'entrée est un int. Mais le nombre d'entrée doit être dans une plage de -2055 à 2055 et je veux le vérifier en utilisant l'expression régulière.
Donc, il y a de toute façon d'écrire une expression régulière pour vérifier si un nombre est (-2055, 2055) ou pas ?
Il est plus facile d'utiliser une instruction if pour vérifier si le numéro est dans la gamme ou pas. Mais je suis en train d'écrire un interprète donc je dois utiliser les regex pour vérifier le nombre d'entrée
- Pourquoi une regex? Il est beaucoup plus facile d'utiliser un
<
et>
de l'opérateur, n'est-ce pas? - Tous les regex solutions sont incomplètes ou erronées en ce moment. Cela peut vous donner un aperçu de pourquoi une regex n'est pas le bon outil pour ce travail. Surtout si vous avez eu pour la modifier plus tard...
- Vous avez raison, Tim! Trung, Tim ont raison. Ce n'est pas plus facile ou plus difficile, son sujet pour ce qu'il est mieux d'atteindre et de résoudre le problème.
- Je suis en train d'écrire un interpréteur OCaml .... comment puis-je valider le nombre d'entrée dans la plage sans utiliser la regex ??
- J'ai soumis deux regexes qui sont absolument valide. L'un est lente et bête, l'autre grave, mais ils sont à la fois solides regex solutions.
- Je suis d'accord que la regex n'est pas le bon outil pour le travail, quand un simple si-plus-que-et-moins-que serait suffisant, mais il est certainement possible.
- Votre stupide version est correcte, l'autre l'on pourrait (selon le moteur d'expressions régulières utilisées) correspondent pas correctement car par exemple dans .NET,
\d
correspond à un beaucoup plus que simplement les chiffres0-9
. - J'ai changé le
\d
s à[0-9]
. Merci. - la nôtre n'est pas à cause de ça. c'est la beauté de stackoverflow - réponses, même à des questions qui semblent ridicules. de bons conseils devrait toujours être accordée même si, comme il a été ici - bien que peut-être un peu plus de force que ce que je suis habitué à voir sur ce site.
- tu veux dire "en cliquant sur le gris de la coche". Il ne s'allume pas en vert jusqu'à ce que Trung prend des mesures...
- Il est toujours vert pour moi 😉
- Veuillez jeter un oeil à mon post aussi.
- Il existe d'autres moyens en OCaml! J'ai posté un OCaml-anwser.
- Je vais souligner que, si la regex est d'une terrible façon de décrire un intervalle entier, en train de faire la vérification de plage avec un automate fini déterministe (DFA, qui est le plus efficace de reconnaissance de la régulièrement des ensembles) est une belle idée. Le DFAE est susceptible d'être plus rapide que la conversion de chiffres d'un entier binaire. Dans une application comme IP plage de vérification dans un pare-feu où la performance est critique, ce qui peut être important. Je me rends compte ce n'est probablement pas le cas des OP prévu de cas d'utilisation, mais juste dire...
- double possible de Expression Régulière: Numérique, gamme
- J'ai créé pour-regex-plage pour automatiser cela, si quelqu'un est intéressé par un javascript de mise en œuvre.
- J'ai créé une application java basée sur la mise en œuvre, qui génère automatiquement des expressions régulières qui n'accepte que des nombres entiers à l'intérieur d'une certaine plage github.com/julianthome/ranger
Vous devez vous connecter pour publier un commentaire.
L'aide d'expressions régulières pour valider une plage numérique
Pour être clair: Quand une si simple déclaration suffira
l'aide d'expressions régulières pour la validation numérique des plages n'est pas recommandé.
En outre, depuis des expressions régulières analyser les chaînes de caractères, nombres doivent d'abord être convertis en une chaîne de caractères avant de pouvoir être testé. Une exception est lorsque le nombre advient-il déjà être une chaîne de caractères, comme lors de l'obtention de la saisie de l'utilisateur à partir de la console.
(Pour s'assurer que la chaîne est un nombre pour commencer, vous pouvez utiliser
org.apache.commons.lang3.math.NumberUtils#isNumber(s)
)En dépit de cela, essayer de comprendre comment valider les plages de numéros avec des expressions régulières est intéressant et instructif.
(Les liens dans cette réponse, viennent de la Débordement de la pile d'Expressions Régulières FAQ.)
Un numéro de plage
la Règle: Un certain nombre doit être exactement
15
.La plus simple de la gamme, il y est. Une expression régulière pour rechercher c'est
Les limites de mot sont nécessaires pour éviter une correspondance de la
15
à l'intérieur de8215242
.Un nombre deux gamme
La règle: Le nombre doit être compris entre
15
et16
. Voici trois regexes:(Les groupes sont nécessaires pour l "ou en"-ing, mais ils pourraient être non-capture:
\b(?:15|16)\b
)Un numéro de plage "en miroir" autour de zéro
La règle: Le nombre doit être compris entre
-12
et12
.Voici une regex pour
0
par12
positive seulement:Gratuit interligne:
Faire ce travail pour à la fois négatif et positif, c'est aussi simple que l'ajout d'un en option tiret au début:
(Ce qui suppose inopportunes caractères précéder le tableau de bord.)
À interdire nombres négatifs, un négatif lookbehind est nécessaire:
Laissant la lookbehind sortir serait la cause de la
11
dans-11
de match. (Le premier exemple de ce poste doit avoir cette ajoutés.)Remarque:
\d
contre[0-9]
Afin d'être compatible avec tous les regex saveurs, de toutes les
\d
-s doit être modifié pour[0-9]
. Par exemple, .NET estime non ASCII des chiffres, tels que ceux dans différentes langues, comme les valeurs pour\d
. Sauf dans le dernier exemple, pour des raisons de concision, c'est à gauche que\d
.(merci à @TimPietzcker)
Trois chiffres, avec tous mais le premier chiffre égal à zéro
la Règle: Doit être entre
0
et400
.Un possible regex:
Gratuit espacés:
Une autre possibilité qui doit jamais utilisé:
Dernier exemple: Quatre chiffres, en miroir autour de zéro, qui ne prend pas fin avec des zéros.
la Règle: Doit être entre
-2055
et2055
C'est à partir d'un question sur stackoverflow.
Regex:
Debuggex Démo
Gratuit interligne:
(merci à PlasmaPower et Casimir et Hippolyte pour le débogage de l'aide.)
Note finale
Selon ce que vous la capture, il est probable que tous les sous-groupes doivent être effectuées dans des groupes de capture. Par exemple, ceci:
Au lieu de cela:
Exemple Java mise en œuvre
}
Sortie
Original de la réponse à cette stackoverflow question
C'est une réponse sérieuse, qui s'adapte à vos spécifications. Il est similaire à @PlasmaPower de réponse.
Debuggex Démo
001
(zéros),-0
(signé zéro), je suggère de modifier le troisième élément de l'alternance et à ajouter de nouvelles alternatives:(-?\b(?:20(?:5[0-5]|[0-4][0-9])|1[0-9]{3}|[1-9][0-9]{0,2})|\b0)\b
-0
entièrement). J'ai aussi déplacé le zéro alternative dans la main "ou" non-groupe de capture.Donc beaucoup de réponses, mais personne ne lit (ou de soins) à propos de la Fpo côté de la question dans les commentaires?
Comme autant de réponses, à juste titre, souligné que l'utilisation de regex est horrible pour ce scénario, permet de penser à d'autres façons d'OCaml! C'est un moment depuis que j'ai utilisé OCaml, mais avec un peu de constructions, j'ai été en mesure de frapper cet ensemble:
Si quelque chose n'est pas clair, veuillez lire sur sa syntaxe, fonctions de conversion de type et la gestion des exceptions et d'entrée-sortie fonctions.
L'entrée de l'utilisateur partie est utilisée uniquement pour le démontrer. Il peut être plus pratique d'utiliser le
read_int
y fonctionner. Mais le concept de base de la manipulation de l'exception reste le même.Analyser le problème
Si vous "doit" utiliser une regex, diviser le problème en analysant les accepté de permutations.
"une gamme de -2055 à 2055" peut être exprimé comme:
"Un nombre de 0 à 2055" peut être l'un d'un nombre fini de permutations spécifiques:
Noter que, pour les fins de cette expression, il n'est pas nécessaire de faire une distinction entre la gamme "0-9" et "1 à 9", et seules les deux dernières plages ont des restrictions sur la plage de accepté de chiffres/caractères (indiqué par une étoile).
Écrire composant les expressions régulières
Chacun de ces composants sont faciles à exprimer individuellement comme une expression régulière:
Mettre l'ensemble des expressions
L'expression pertinente pour l'ensemble du match serait:
Ou légèrement de façon plus concise:
En supposant l'entrée ne contient que "le nombre" et rien d'autre, la finale de la regex est donc:
Si c'est nécessaire pour permettre l'un des principaux signe plus, cela devient:
Voici un js fiddle démonstration de ce qui passe et ce qui serait d'échec de la dernière regex.
Pourquoi utiliser des Regex seulement à vérifier un certain nombre?
Une alternative à l'approche de la grande expression offerts par aliteralmind, en voici un qui est beaucoup plus long mais intéressant de voir ce qu'une autre approche pourrait ressembler (et quoi ne pas faire).
C'est un exercice intéressant, parce que vous pouvez penser deux distincts méthode: en gros, vous pouvez soit:
Sans essayer, comment voulez-vous savoir lequel est le meilleur? Il s'avère que la première approche (aliteralmind de réponse) est beaucoup plus économique.
Plus bas, je comprend un série de tests dans le langage PHP dans le cas où vous ou que quelqu'un d'autre, comme pour vérifier la sortie.
Ci-dessous, je vais vous donner les regex en "free-mode d'espacement", qui permet d'émettre des commentaires à l'intérieur de la regex de sorte que vous pouvez facilement comprendre ce qu'il fait. Cependant, pas tous les regex moteurs en charge le mode d'espacement, donc avant de commencer avec la partie intéressante, voici la regex comme un one-liner.
Noter que votre question mentionne les numéros de -2055 à 2055. Je suppose que tu voulais faire correspondre des nombres normaux", sans les zéros à gauche. Cela signifie que la regex va correspondre à 999, mais pas 0999. Si vous souhaitez les zéros à gauche, faites le moi savoir, qui est très facile à modifier.
Aussi, si vous faites une comparaison en mode utf-8, le
\d
devrait être remplacé par[0-9]
. C'est la forme la plus commune.La Regex comme un One-Liner
Les Regex en Libre-Mode d'Espacement
Série de Tests
Ces tests essayer de faire correspondre les numéros de -100000 à 100000. Ils produisent à la sortie suivante:
Voici le code:
Des Tests De Vitesse De
Voici la sortie de mon simple test de vitesse, de correspondance de -1 à +1M. Comme Casimir souligné, si aliteralmind de l'expression qui étaient à l'ancre, au lieu d'être plus lent, il serait plus rapide de 25%!
Voici le code de test:
^
à alitermind motif, vous verrez un résultat très différent. L'ajout d'un point d'ancrage pour un motif est la première optimisation point.^
le même test montre aliteralmind de la regex pour être 25% plus vite.Essayez ceci:
\-?\d{1,2}
(oups)-09
mais pas999
(seulement0999
)...-99
à99
. Et elle permet tout de même0999
...1२۱۲
et d'autres numéros de chiffres non-ASCII...d'habitude, la regex n'est pas l'outil à utiliser.Découvrez ce formidable outil qui génère une regex pour les plages numériques:
http://gamon.webfactional.com/regexnumericrangegenerator/
Pour la plage demandée par l'OP il génère:
-?([0-9]{1,3}|1[0-9]{3}|20[0-4][0-9]|205[0-5])
Essayer avec un très simple regex.
Représentation visuelle
C'est très simple à comprendre.
[-0][0-1][0-9][0-9][0-9]
couvrira [-1999, 1999] valeurs[-0]20[0-4][0-9]
couvrira [-2000,-2049] et [2000,2049] valeurs[-0]205[0-5]
couvrira [-2050, -2055] et [à 2050 2055] valeursExemple de code: (Lire les commentaires en ligne pour plus de clarté.)
de sortie:
[-0]
. Il doit correspondre à un-
ou un0
, donc les nombres comme123
ne correspond pas, sauf s'il est précédé d'un0
, comme dans0123
...String.format("%05d", number)
.Essayez ceci:
La regex avant les parenthèses correspond à une option
-
et tous les premiers 0s.La première partie entre parenthèses (
1?[0-9]{1,3}
) correspond à 0-1999.La deuxième partie entre parenthèses (
20[0-4][0-9]
) correspond à 2000-2049.La troisième partie entre parenthèses (
205[0-5]
) correspond à 2050-2055.Encore un autre -