Perl正则表达式替换字边界.将"/"检测为单词边界

0 regex perl word-boundary

我遇到了一个奇怪的正则表达式问题....我有一个文件,我正在做一个替换...作为一个例子,我想用"DEXX/AREX"替换"DEXX",然后用下一个替换替换.. ."AREX"与"AREX/CUBE"

DEXX和AREX存储在哈希中,如此......"DEXX"=>"AREX","AREX"=>"CUBE"

我有的正则表达是这.....

foreach (keys %hashstore){
    $doc=~s!\b($_)\b!$1/$hashstore{$_}!ig;
}
Run Code Online (Sandbox Code Playgroud)

发生的事情是"DEXX"正在被"DEXX/AREX"取代,但是当遇到"DEXX/AREX"时,正则表达式正在替换"DEXX/AREX"和"DEXX/AREX/CUBE",只应该替换"DEXX/AREX" AREX"当它发现它是一个独立的单词而不是像"DEXX/AREX"这样的另一个组合的一部分

它似乎将"/"检测为单词边界.有没有人遇到这个或知道它周围的解决方案?非常感谢!艾米

Sin*_*nür 5

但是/是一个单词边界.来自perldoc perlreref:

\b匹配单词边界(在\w和之间\W).

根据您在下面的评论,您应该避免循环:

#!/usr/bin/perl

use strict; use warnings;
use Regex::PreSuf;

my %lookup = (
    "DEXX" => "AREX",
    "AREX" => "CUBE",
);

my $doc = 'DEXX AREX AREX DEXX AREX DEXX DEXX DEXX AREX';
my $re = presuf keys %lookup;

$doc =~ s{($re)}{$1/$lookup{$1}}g;

print $doc, "\n";
Run Code Online (Sandbox Code Playgroud)

输出:

DEXX/AREX AREX/CUBE AREX/CUBE DEXX/AREX AREX/CUBE DEXX/AREX DEXX/AREX DEXX/AREX
AREX/CUBE

当然,如果您只有两个键,则不必使用Regex :: PreSuf:

s{(AREX|DEXX)}{$1/$lookup{$1}}g;
Run Code Online (Sandbox Code Playgroud)

也会这样做.但是,对于更长的密钥列表,我发现Regex :: PreSuf非常方便.

更新:当然,如果文本中的任何键都可以出现,您可以uc在查找替换时进行转换:

所以,要么

$doc =~ s{($re)}{join '/', uc($1), $lookup{uc $1}}eig;
Run Code Online (Sandbox Code Playgroud)

要么

$doc =~ s{($re)}{join '/', $1, $lookup{uc $1}}eig;
Run Code Online (Sandbox Code Playgroud)

取决于你需要什么.

此外,ysth在评论中指出"使用5.10及更高版本,在大多数情况下,Regex :: PreSuf生成比正常交替更差的正则表达式." 所以,

my $re = join '|', map quotemeta, sort { length($b) <=> length($a) } keys %lookup; 
Run Code Online (Sandbox Code Playgroud)

可能会更好.该sort如果某些键可能是其他键的初始子是必要的.

  • @Amy Wilkins:报告没有错误,除了你在查找哈希中查找一个键而不是哈希使用的情况,所以你得到一个undef (2认同)