Reputation: 168
I doubt it's possible, but I haven't found anything to specifically say it's not possible. But is there some way to construct a parallel alternation in a search and replace regex? So, for example, if I wanted to replace street types with their abbreviations, could I do something like this:
s/(STREET|AVENUE|BOULEVARD)/(ST|AVE|BLVD)/
without having the entire rhs substituted in? Or do I really have to do separate replaces for each street type?
Upvotes: 0
Views: 874
Reputation: 164
Well, the first two substrings aren't too difficult:
import re
s = 'street'; a = 'avenue'; b = 'boulevard'
re.sub(r'(str)eet|(ave)nue|(boulevard)', r'\1 \2 \3', s)
re.sub(r'(str)eet|(ave)nue|(boulevard)', r'\1 \2 \3', a)
re.sub(r'(str)eet|(ave)nue|(boulevard)', r'\1 \2 \3', b)
The last three lines return matches plus white space for the groups that weren't matched. I think one may have to do further processing on the string in order to get 'blvd' from 'boulevard' were it to be captured by the above regex. That's reasonable though, since extracting a set of substrings from 'boulevard' is a separate issue from capturing and replacing one of a set of alternate regexes.
Perhaps, since this way already requires the extra step of removing whitespace, one could do something like this:
#with boulevard
new_str = re.sub(r'(str)eet|(ave)nue|(b)oulevard', r'\1 \2 \3lvd', b)
re.sub(r'\s+|\blvd', '', new_str)
#with avenue
new_str = re.sub(r'(str)eet|(ave)nue|(b)oulevard', r'\1 \2 \3lvd', a)
re.sub(r'\s+|\blvd', '', new_str)
The code looks kinda funny though.
Upvotes: -1
Reputation: 8332
This isn't that pretty, but it'll get the job done:
Replace
(?:(ST)REET|(AVE)NUE|(B)OU(L)E(V)AR(D))
with
\1\2\3\4\5\6
It matches the words, capturing the relevant parts. Replace with all capture groups and the relevant parts are inserted.
Upvotes: 3
Reputation: 89639
For the fun, and for these three words only in PCRE/Perl/Python regex module/npp:
(?:\G(?!^)|\b(?=(?:STREET|AVENUE|BOULEVARD)\b))[A-Z]*?\K(?:TREE|E(?:NU)?|OU|AR)\B
replace with the empty string.
or this one:
\G[A-Z]*?(?>\W*\b(?>\w+\W+)*?(?=(?:STREET|AVENUE|BOULEVARD)\b))?[A-Z]*?\K(?:TREE\B|E(?:NU)?\B|OU\B|AR\B)
Upvotes: 3
Reputation: 104092
In Python, you would use a call back to a dictionary like so:
>>> abs={'STREET':'ST', 'AVENUE':'AVE','BOULEVARD':'BLVD'}
>>> re.sub(r'(STREET|AVENUE|BOULEVARD)', lambda m: abs[m.group(1)], 'Fourth STREET')
'Fourth ST'
In Perl, you can do:
use strict;
use warnings;
my %abs=(
'STREET', 'ST',
'AVENUE' ,'AVE',
'BOULEVARD', 'BLVD'
);
$_='Fourth STREET';
s/(STREET)|(AVENUE)|(BOULEVARD)/$abs{$1}/ && print;
Upvotes: 2
Reputation: 7880
It depends on language or tool you are using. For example, using Notepad++, you can replace
(STREET)|(AVENUE)|(BOULEVARD)
with:
(?1ST)(?2AVE)(?3BLVD)
Upvotes: 1