Chris
Chris

Reputation: 1483

python regex: match a string with only one instance of a character

Suppose there are two strings:

$1 off delicious ham.
$1 off delicious $5 ham.

In Python, can I have a regex that matches when there is only one $ in the string? I.e., I want the RE to match on the first phrase, but not on the second. I tried something like:

re.search(r"\$[0-9]+.*!(\$)","$1 off delicious $5 ham.")

..saying "Match where you see a $ followed by anything EXCEPT for another $." There was no match on the $$ example, but there was also no match on the $ example.

Thanks in advance!

Simple test method for checking:

def test(r):
  s = ("$1 off $5 delicious ham","$1 off any delicious ham")    
  for x in s:
    print x
    print re.search(r,x,re.I)
    print ""

Upvotes: 9

Views: 20088

Answers (5)

MattH
MattH

Reputation: 38247

>>> import re
>>> onedollar = re.compile(r'^[^\$]*\$[^\$]*$')
>>> onedollar.match('$1 off delicious ham.')
<_sre.SRE_Match object at 0x7fe253c9c4a8>
>>> onedollar.match('$1 off delicious $5 ham.')
>>>

Breakdown of regexp:
^ Anchor at start of string
[^\$]* Zero or more characters that are not $
\$ Match a dollar sign
[^\$]* Zero or more characters that are not $
$ Anchor at end of string

Upvotes: 12

SilentGhost
SilentGhost

Reputation: 319531

>>> '$1 off delicious $5 ham.'.count('$')
2
>>> '$1 off delicious ham.'.count('$')
1

Upvotes: 7

fmark
fmark

Reputation: 58547

You want to use the complement of a character class [^] to match any character other than $:

re.match(r"\$[0-9]+[^\$]*$","$1 off delicious $5 ham.")

The changes from your original are as follows:

  1. .* replaced with [^\$]*. The new term [^\$] means any character other than $
  2. $ appended to string. Forces the match to extend to the end of the string.
  3. re.search replaced with re.match. Matches the whole string, rather than any subset of it.

Upvotes: 2

dweeves
dweeves

Reputation: 5605

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

this should make the trick

Upvotes: 1

John La Rooy
John La Rooy

Reputation: 304137

re.search("^[^$]*\$[^$]*$",test_string)

Upvotes: 1

Related Questions