Oliver Zheng
Oliver Zheng

Reputation: 8199

Match a string that does not end with a list of known strings

I want to match street names, which could come in forms of " St/Ave/Road". The postfix may not be exist at all, so it may just be "1st". I also want to know what the postfix is. What is a suitable regex for it? I tried:

(.+)(\s+(St|Ave|Road))?

But it seems like the first group greedily matches the entire string. I tried a look back (?<!), but couldn't get it to work properly, as it kept on spewing errors like "look-behind requires fixed-width pattern".

If it matters at all, I'm using Python.

Any suggestions?

Upvotes: 2

Views: 2629

Answers (4)

Bohemian
Bohemian

Reputation: 425398

How about negative look behind:

(?!<=(St|Ave|Road))$

it seems to express the requirement closely

Upvotes: 0

NPE
NPE

Reputation: 500913

As an alternative to regex-based solutions, how about:

suffix = s.split(' ')[-1]
if suffix in ('St', 'Ave', 'Road'):
  print 'suffix is', suffix
else:
  print 'no suffix'

If you do have to use regular expressions, simply make the first match non-greedy, like to: r'.*?\s+(St|Ave|Road)$'

In [28]: print re.match(r'(.*?)\s+(St|Ave|Road)$', 'Main Road')
<_sre.SRE_Match object at 0x260ead0>

In [29]: print re.match(r'(.*?)\s+(St|Ave|Road)$', 'nothing here')
None

Upvotes: 3

cababunga
cababunga

Reputation: 3114

You wanted negative look ahead

(?!(St|Ave|Road))$

Upvotes: 0

Frank Schmitt
Frank Schmitt

Reputation: 30845

Just make your first group non-greedy by adding a question mark:

(.+?)(\s+(St|Ave|Road))?

Upvotes: 4

Related Questions