2009-09-27 6 views
2

Je veux vérifier une chaîne qui contient la période, ".", Au plus une fois en python.regex pour le caractère apparaissant au plus une fois

+0

Pouvez-vous donner quelques exemples de ce qui serait des chaînes valides, et quelles seraient les chaînes invalides? La question est un peu vague. Par exemple, peut-il y avoir des caractères entre les périodes? Parlez-vous seulement des caractères consécutifs ou de tous les caractères de la chaîne? –

+0

Je veux vérifier les entiers et les nombres décimaux. Donc, les chaînes valides dans ce cas seraient 2.34 ou 2. Les chaînes non valides seraient 2.2.3. En fait, ce que j'ai en ce moment est ceci: [sinon re.search ("[0-9 \.] + $", Item) ou non re.search ("^ * \.? * $", Item) : retourne "valeur invalide"]. Si vous connaissez un meilleur moyen, s'il vous plaît faites le moi savoir. Merci! – teggy

Répondre

7
[^.]*\.?[^.]*$ 

Et assurez-vous de match, ne search

>>> dot = re.compile("[^.]*\.[^.]*$") 
>>> dot.match("fooooooooooooo.bar") 
<_sre.SRE_Match object at 0xb7651838> 
>>> dot.match("fooooooooooooo.bar.sad") is None 
True 
>>> 

Modifier:

Si l'on considère que des entiers et décimaux, il est encore plus facile :

def valid(s): 
    return re.match('[0-9]+(\.[0-9]*)?$', s) is not None 

assert valid("42") 
assert valid("13.37") 
assert valid("1.") 
assert not valid("1.2.3.4") 
assert not valid("abcd") 
+1

Si vous avez un '^' au début de l'expression, ou est-ce implicite parce que vous correspondez? –

+0

c'est implicite, correct;) – NicDumZ

+0

[Explicit est mieux que implicite] (http://www.python.org/dev/peps/pep-0020/), donc il devrait y avoir un '^' au début de l'expression . – Bengt

0

Si la période est un caractère spécial, elle doit être échappée. Donc "\. +" Devrait fonctionner.

EDIT:

Utilisez '?' au lieu de '+' pour correspondre à une répétition ou zéro. Jetez un oeil à: re — Regular expression operations

+1

Cela correspond à la période 1 fois ou plus. Je pense que la question veut 0 ou 1 fois. –

+0

Vous avez raison. En regexp plus signifie un ou plusieurs. Je devrais utiliser un point d'interrogation au lieu de plus. –

2

Vous pouvez utiliser:

re.search('^[^.]*\.?[^.]*$', 'this.is') != None 

>>> re.search('^[^.]*\.?[^.]*$', 'thisis') != None 
True 
>>> re.search('^[^.]*\.?[^.]*$', 'this.is') != None 
True 
>>> re.search('^[^.]*\.?[^.]*$', 'this..is') != None 
False 

(. Matches période zéro ou une fois)

0

Si la période devrait exister qu'une seule fois dans l'ensemble de la chaîne, puis utilisez l'opérateur ?:

^[^.]*\.?[^.]*$ 

Rupture de cette valeur:

  1. ^ correspond au début de la chaîne
  2. [^.] correspond à zéro ou plusieurs caractères qui ne sont pas des périodes
  3. \.? correspond au caractère de période (doit être échappé avec \ comme il est char réservé) exactement 0 ou 1 fois
  4. [^.]* est le même modèle utilisé dans 2 ci-dessus
  5. $ correspond à la fin de la chaîne

en aparté, personnellement, je ne voudrais pas utiliser une expression régulière pour cela (à moins que j'étais chec roi d'autres aspects de la chaîne pour la validité aussi). Je voudrais juste utiliser la fonction de comptage.

+0

Sauf si vous vous assurez que vous correspondez à la chaîne * whole *, cela correspondra à ".." (regex correspond à la première période, puis se termine sans tenir compte de la deuxième période). – Richard

+0

Assez vrai. Réponse mise à jour –

+0

Ceci ne couvre pas le cas où une chaîne contient deux périodes avec d'autres lettres entre elles. – davidi

5

Aucune expression rationnelle est nécessaire, voir str.count():

str.count(sub[, start[, end]])

Retourne le nombre d'occurrences non-chevauchement des sous-chaîne dans l'intervalle [début, fin]. Les arguments optionnels start et end sont interprétés comme des notations de tranches.

>>> "A.B.C.D".count(".") 
3 
>>> "A/B.C/D".count(".") 
1 
>>> "A/B.C/D".count(".") == 1 
True 
>>> 
0

Pourquoi avez-vous besoin de vérifier? Si vous avez un nombre dans une chaîne, je suppose que vous voudrez le traiter sous peu.Peut-être que vous pouvez le faire sans avant de sauter Vous:

try: 
    value = float(input_str) 
except ValueError: 
    ... 
else: 
    ... 
Questions connexes