1

問題:

で囲まれたファイル内のテキストを検索し@、内部を置き換えます

入力:

@abc@ abc @ABC@
cba @cba CBA@

必要な出力:

абц abc АБЦ
cba цба ЦБА

私は次のものを持っています:

#!/usr/bin/perl
use strict;
use warnings;
use Encode;
my $output;
open FILE,"<", 'test.txt';
while (<FILE>) {
    chomp(my @chars = split(//, $_));
    for (@chars) {
        my @char;
        $_ =~ s/a/chr(0x430)/eg;
        $_ =~ s/b/chr(0x431)/eg;
        $_ =~ s/c/chr(0x446)/eg;
        $_ =~ s/d/chr(0x434)/eg;
        $_ =~ s/e/chr(0x435)/eg;
        $_ =~ s/A/chr(0x410)/eg;
        $_ =~ s/B/chr(0x411)/eg;
        $_ =~ s/C/chr(0x426)/eg;
        push @char, $_;
        $output = join "", @char;
        print encode("utf-8",$output);}
print "\n";
}
close FILE;

しかし、私はさらに処理する方法に固執しています

よろしくお願いします!

Kluther

4

4 に答える 4

2

ここに私の解決策があります。(あなたはそれを修正します、はい。それはプロトタイプです)

for (my $data = <DATA>){
    $data=~s/[@]([\s\w]+)[@]/func($1)/ge;
    print $data;
#   while($data=~m/[@]([\s\w]+)[@]/g){
#      print "marked: ",$1,"\n";
#      print "position:", pos();
#   }
#      print "not marked: ";
}
sub func{
   #do your magic here ;)
   return "<< @_ >>";
}
__DATA__
@abc@ abc @ABC@ cba @cba CBA@

そこで何が起こるの?

まず、データを読み取ります。あなたはそれを自分で行うことができます。

for (my $data = <DATA>){...}

次に、パターンを検索して置換する必要があります。
私は何をすべきか?

使用するsubstition operator: s/pattern/replace/

しかし、興味深い形で:

s/pattern/func($1)/ge

キーg平均グローバル検索

主要なe平均 評価する

したがって、独自の関数を作成する必要があると思いますfunc;)

使ったほうがいいかもtransliteration operator: tr/listOfSymbolsToBeReplaced/listOfSymbolsThatBePlacedInstead/

于 2013-03-08T11:24:42.103 に答える
0

処理後にこれを試してください$output

$output =~ s/\@//g;
my @split_output = split(//, $output);
$output = "";
my $len = scalar(@split_output) ;
while ($len--) {
    $output .= shift(@split_output);
}
print $output;
于 2013-03-08T11:16:10.087 に答える
0

これは、単一の正規表現を使用して、文字列を分割せずに実行できます。

use strict;
use warnings;
use Encode;

my %chars = (
    a => chr(0x430),
    b => chr(0x431),
    c => chr(0x446),
    d => chr(0x434),
    e => chr(0x435),
    A => chr(0x410),
    B => chr(0x411),
    C => chr(0x426),
);

my $regex = '(' . join ('|', keys %chars) . ')'; 


while (<DATA>) {
    1 while ($_ =~ s|\@(?!\s)[^@]*?\K$regex(?=[^@]*(?!\s)\@)|$chars{$1}|eg);
    print encode("utf-8",$_);
}

一致の性質が重複しているため、正規表現を繰り返し実行する必要があります。

于 2013-03-08T11:16:56.843 に答える
0

@アルゴリズムに最小限の変更を加えて、マークの内側にいるかどうかを追跡する必要があります。このようなものを追加します

my $bConvert = 0;
chomp(my @chars = split(//, $_));
for (@chars) {
    my $char = $_;
    if (/@/) {
        $bConvert = ($bConvert + 1) % 2;
        next;
    }
    elsif ($bConvert) {
        $char =~ s/a/chr(0x430)/eg;
        $char =~ s/b/chr(0x431)/eg;
        $char =~ s/c/chr(0x446)/eg;
        $char =~ s/d/chr(0x434)/eg;
        $char =~ s/e/chr(0x435)/eg;
        $char =~ s/A/chr(0x410)/eg;
        $char =~ s/B/chr(0x411)/eg;
        $char =~ s/C/chr(0x426)/eg;
    }
    print encode("utf-8",$char);
}
于 2013-03-08T11:21:27.340 に答える