可以使用正则表达式替换吗?

时间:2016-09-27 19:43:37

标签: regex

我怀疑这是可能的,但我还没有找到任何具体的说法,这是不可能的。但是有没有办法在搜索中构建并行交替并替换正则表达式?所以,例如,如果我想用他们的缩写替换街道类型,我可以做这样的事情:

s/(STREET|AVENUE|BOULEVARD)/(ST|AVE|BLVD)/ 

没有取代整个rhs?或者我是否真的必须为每种街道类型单独替换?

5 个答案:

答案 0 :(得分:3)

这不是 漂亮,但它会完成工作:

替换

(?:(ST)REET|(AVE)NUE|(B)OU(L)E(V)AR(D))

\1\2\3\4\5\6

匹配单词,捕获相关部分。替换为所有捕获组,并插入相关部分。

See it here at regex101

答案 1 :(得分:3)

为了好玩,仅在PCRE / Perl / Python正则表达式模块/ npp中使用这三个单词:

(?:\G(?!^)|\b(?=(?:STREET|AVENUE|BOULEVARD)\b))[A-Z]*?\K(?:TREE|E(?:NU)?|OU|AR)\B

替换为空字符串。

demo

或者这个:

\G[A-Z]*?(?>\W*\b(?>\w+\W+)*?(?=(?:STREET|AVENUE|BOULEVARD)\b))?[A-Z]*?\K(?:TREE\B|E(?:NU)?\B|OU\B|AR\B)

demo

答案 2 :(得分:2)

在Python中,您可以像这样使用回调字典:

>>> abs={'STREET':'ST', 'AVENUE':'AVE','BOULEVARD':'BLVD'}
>>> re.sub(r'(STREET|AVENUE|BOULEVARD)', lambda m: abs[m.group(1)], 'Fourth STREET')
'Fourth ST'

在Perl中,你可以这样做:

use strict;
use warnings;

my %abs=(
    'STREET', 'ST',
    'AVENUE' ,'AVE',
    'BOULEVARD', 'BLVD'
);
$_='Fourth STREET';
s/(STREET)|(AVENUE)|(BOULEVARD)/$abs{$1}/ && print;

答案 3 :(得分:1)

这取决于您使用的语言或工具。例如,使用Notepad ++,您可以替换

(?1ST)(?2AVE)(?3BLVD)

使用:

{{1}}

答案 4 :(得分:-1)

嗯,前两个子串并不太难:

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)

最后三行返回匹配项以及未匹配的组的空白区域。我认为可能需要对字符串进行进一步处理,以便从'boulevard'获得'blvd',如果它被上面的正则表达式捕获。这是合理的,因为从'boulevard'中提取一组子串是捕获和替换一组备用正则表达式中的一个单独的问题。

也许,因为这种方式已经需要额外的步骤来删除空格,所以可以这样做:

#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)

但代码看起来很有趣。