REGEX intervalle de nombre et exclusions de certains

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

Je suis en train de m’arracher les cheveux en construisant différentes regex, entre autre, sur des intervalles de nombre. En faisant cela, je me pose quelques questions.

JE dois faire une regex pour que match l’intervalle 001 à 999 (et pas 1 à 999, ni 000) j’ai trouvé cela : ([1–9][0-9]{2}|0[1–9][0-9]|00[1–9]).

Le plus simple aurait été [0–9]{3}, mais cela matche "000". Comment exclure "000" de cette dernière solution.

Par ailleurs, n’y a-t-il pas de formule plus simple pour exprimer un interval de nombre, genre de 46 à 768 ?

MErci à tous pour votre aide.

Bonne journée

Bonjour @netchaiev,

Pourquoi veux tu absolument 001 et pas 1 ? Puisque tu peux facilement afficher 001 avec une valeur de 1 en faisant un "left-pad" de 0.

# en python
str(1).zfill(3)
# output: '001`

Le plus simple serait de travailler avec des entiers et de faire une vérification avec un if:

if 0 < valeur <= 999:
   print(str(valeur).zfill(3))

Si tu travailles sur des chaînes de caractères:

Si tu veux absolument avoir 001–999, tu peux écrire ^(00[1-9]|0[1-9][0-9]|[1-9][0-9][0-9])$. Donc ce que tu as écris est bon. Si la solution du "left-pad" est possible, tu peux légèrement simplifier avec ça ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$.

Pour utiliser directement ^[0-9]{3}$ et exclure 000, tu peux utiliser un negative lookahead: ^(?!000)\d{3}$

Pour ce qui est de l’intervalle du type 46 à 768, je ne vois pas de solution miracle par contre.

+0 -0

Les regex travaillent au niveau des chaînes de caractères. Pas au niveau de leur interprétation.

"45" c’est juste le caractère '4' et '5' l’un après l’autre, rien à voir avec le nombre 45.

Pour les regex, travailler directement au niveau d’intervals n’a pas de sens. C’est pour cela qu’il est compliqué de vérifier qu’un nombre est entre deux autres nombre avec une regex.

+2 -0

MErci à tous les deux pour vos réponses et éclaircissements.

@thibsc : Je suis bien d’accord avec toi, il eut été préférable d’utiliser 1 à 999, le problème c’est que les regex que je dois faire sont là pour veiller à ce qui est entré par un utilisateur, sur une BDD. Et il a été décidé à l’époque que champs de 4 digits s’écrivait comme cela 00001 -> 9999. Je n’ai pas cherché à comprendre, puisque la BDD est faite

En tout cas merci pour l’exclusion, je tournais en rond sans finaliser le truc.

@ache : Merci pour cette explication sur la recherche (uniquement de caractère). Je pensais que les regex pouvaient interpréter un chaine comme un int. Je me suis trompé donc.

Merci à tous les deux.

Salut,

J’ai envie de dire que tu es dans un cas où utiliser une regex semble être une bonne idée mais n’en est pas vraiment une.

Quelque chose comme

def check_string(string):
    try:
        num = int(string)
    except ValueError:
        return False
    return 0 < num < 1000 and f'{num:03d}' == string

pour vérifier que ta chaîne est au bon format est plus verbeux mais surtout plus lisible et bien plus flexible (et c’est ça qui compte dans un code). Avoir un intervalle arbitraire devient un jeu d’enfant, et changer le nombre de 0 aussi. Avec une regex, c’est même pas forcément possible sans se retrouver avec un nombre de cas gigantesque.

+1 -0

Si la solution du "left-pad" est possible, tu peux légèrement simplifier avec ça ^([1-9]|[1-9][0-9]|[1-9][0-9][0-9])$

Simplifiable en ^[1-9][0-9]{0,2}$.

mais sinon je suis d’accord avec ce qui est dit, les regex ne sont probablement pas l’outil le plus adapté pour ça

+0 -0

OK je prends bonne note de vos remarques. Je vais effectivement peut-être revoir les choses autrement.

Et puis, cela m’arrange, car les regex et moi on ne fait pas bon ménage. Je m’y mets uniquement si c’est nécessaire, mais alors vraiment vraiment nécessaire. ^^

le problème c’est que les regex que je dois faire sont là pour veiller à ce qui est entré par un utilisateur, sur une BDD. Et il a été décidé à l’époque que champs de 4 digits s’écrivait comme cela 00001 -> 9999.

netchaiev

Dans ce cas, tu peux très bien gérer tes ranges côté programmation avec des entiers, et en fonction de ton SGBD, faire ton left-pad à l’insertion des données:

-- Ex. MariaDB, output: '0003'
select lpad('3', 4, '0');
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte