【问题标题】:Multiple substitutions with a single regular expression with caring about position in perl使用单个正则表达式进行多次替换,关心 perl 中的位置
【发布时间】:2013-04-22 23:51:20
【问题描述】:

我想读入一个文件,格式如下:“string1 string2 string3”并替换掉几个字符,(但每把椅子都应该替换一次) 例如这些规则: tsch=> tch, ch> h, ki=> ky (但只要 ki 位于“单词”的末尾) 所以“tschaiki”应该变得 thaiky 而不是 thaiky(当使用 for 循环或多个单个替代命令时会发生这种情况)

我知道之前有人问过这个问题,并通过在 perl 中创建哈希来解决。

$line=<>
my %replace =(j=> "y", ss=> "s", u=> "ou", tsch=> "ch"); #short versions of the rules
my $regex = join "|", keys %replace;    

$regex = qr/$regex/;
$line=~s/($regex)/$replace{$1}/g;

到目前为止,这对我也有效,但我希望某些字符只能在字符串末尾替换。但这会导致问题: 我已经用第二个正则表达式和哈希扩展了之前的代码,仅用于结尾:

 my %replace_end =(ia=> "iya", ki=> "ky",ei=> "ey" );
 my $regex_end = join "|", keys %replace_end;
 $regex_end = qr/$regex_end/; 
 $line=~s/($regex_end)$/$replace_end{$1}/g;  # saying just to substitute at the end 

我的整个代码如下,但要么出现异常,要么结尾被忽略(我认为没有文件处理和 while 循环的代码确实有效):

#!/usr/bin/perl
use strict;
use warnings;

open(INP,"<:utf8","dt_namen.txt"); 
open(OUT,">:utf8","dt_zu_engl.txt");

my %replace =(j=> "y", ss=> "s", tsch=> "ch", sch => "sh", c => "k", J="Y", Ss=>"s"); 
 my $regex = join "|", keys %replace;  
 $regex = qr/$regex/;

 my %replace_end =(ki=> "ky",ei=> "ey" );
 my $regex_end = join "|", keys %replace_end;
 $regex_end = qr/$regex_end/; 

while(my $line= <INP>){
 $line=~s/($regex)/$replace{$1}/g;
 $line=~s/($regex_end)$/$replace_end{$1}/g;  # saying just to substitute at the end 
 print $line;
 print OUT "$line";
}
close INP;
close OUT;

【问题讨论】:

    标签: regex perl hash file-handling substitution


    【解决方案1】:

    您的代码存在一个潜在问题,即替换顺序未定义。如果两个模式在同一位置匹配,则不知道哪一个会匹配。这完全取决于正则表达式中哪个先出现,并且哈希没有定义的顺序,所以现在没有保证行为。

    通过在构造正则表达式时执行sort 来解决此问题:

    my $regex = join "|", sort {length($b) <=> length($a)} keys %replace;
    

    这将按长度降序对术语进行排序,因此您将确保始终首先匹配最长的术语。

    更新:只替换字符串的末尾,试试这个:

    my $regex_end = join "|", map { qr/$_$/ } keys %replace_end;
    

    它在每个术语的末尾放置一个$(匹配字符串的末尾)。

    或者,如果你的意思是,只替换单词的末尾,这样做:

    my $regex_end = join "|", map { qr/$_\b/ } keys %replace_end;
    

    【讨论】:

    • 好的,谢谢,这是一个很好的提示。总的来说,我想说的是,某些字符只能在字符串的末尾替换,这不起作用。
    猜你喜欢
    • 1970-01-01
    • 2013-05-29
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 2013-02-16
    • 1970-01-01
    • 2016-10-29
    相关资源
    最近更新 更多