我遇到了一个奇怪的正则表达式问题....我有一个文件,我正在做一个替换...作为一个例子,我想用"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"这样的另一个组合的一部分
它似乎将"/"检测为单词边界.有没有人遇到这个或知道它周围的解决方案?非常感谢!艾米
但是/是一个单词边界.来自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如果某些键可能是其他键的初始子是必要的.
| 归档时间: |
|
| 查看次数: |
1903 次 |
| 最近记录: |