Reputation: 6315
I want to check a string that contains the period, ".", at most once in python.
Upvotes: 3
Views: 11821
Reputation: 49803
Why do you need to check? If you have a number in a string, I now guess you will want to handle it as a number soon. Perhaps you can do this without Looking Before You Leap:
try:
value = float(input_str)
except ValueError:
...
else:
...
Upvotes: 0
Reputation: 7231
[^.]*\.?[^.]*$
And be sure to match
, don't search
>>> dot = re.compile("[^.]*\.[^.]*$")
>>> dot.match("fooooooooooooo.bar")
<_sre.SRE_Match object at 0xb7651838>
>>> dot.match("fooooooooooooo.bar.sad") is None
True
>>>
Edit:
If you consider only integers and decimals, it's even easier:
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")
Upvotes: 10
Reputation: 310907
If the period should exist only once in the entire string, then use the ?
operator:
^[^.]*\.?[^.]*$
Breaking this down:
^
matches the beginning of the string[^.]
matches zero or more characters that are not periods\.?
matches the period character (must be escaped with \
as it's a reserved char) exactly 0 or 1 times[^.]*
is the same pattern used in 2 above$
matches the end of the stringAs an aside, personally I wouldn't use a regular expression for this (unless I was checking other aspects of the string for validity too). I would just use the count function.
Upvotes: 0
Reputation: 86362
No regexp is needed, see str.count()
:
str.count(sub[, start[, end]])
Return the number of non-overlapping occurrences of substring sub in the range [start, end]. Optional arguments start and end are interpreted as in slice notation.
>>> "A.B.C.D".count(".")
3
>>> "A/B.C/D".count(".")
1
>>> "A/B.C/D".count(".") == 1
True
>>>
Upvotes: 5
Reputation: 54302
While period is special char it must be escaped. So "\.+" should work.
EDIT:
Use '?' instead of '+' to match one or zero repetitions. Have a look at: re — Regular expression operations
Upvotes: 0
Reputation: 132227
You can use:
re.search('^[^.]*\.?[^.]*$', 'this.is') != None
>>> re.search('^[^.]*\.?[^.]*$', 'thisis') != None
True
>>> re.search('^[^.]*\.?[^.]*$', 'this.is') != None
True
>>> re.search('^[^.]*\.?[^.]*$', 'this..is') != None
False
(Matches period zero or one times.)
Upvotes: 2