3

perl では、マッチに対して別の置換演算子が実行された後に、マッチした文字列をそれ自体で置き換えたい場合がよくあります。たとえば、引用符で囲まれた文字列を見つけてスペースを削除する必要があるアプリケーションがあります。これを行う1つの方法は次のとおりです。

while($str =~ s/"([^"])+"//){
   $temp = $1;
   $temp2 = $temp;
   $temp =~ s/ /_/g;
   $str =~ s/$temp2/$temp1/;
}

これも可能と思われます:

$str =~ s/"([^"])+"/replace_spaces($1)/gx;
sub replace_spaces(){
    $word = shift;
    $word =~ s/ /_/g;
    return $word;
}

どういうわけか正規表現内に正規表現をネストすることによって、これを行う純粋な正規表現の方法はありますか?

4

3 に答える 3

3

当面の特定のタスクについては、Text::ParseWordsを使用することでより適切に処理できます。

#!/usr/bin/env perl

use strict; use warnings;
use feature 'say';
use Text::ParseWords;

my $input = q{This is "a t e s t " string. "Hello - world  !"};
my @words = shellwords $input;

for my $word ( @words ) {
    $word =~ s/ +//g;
    say "'$word'";
}

[文字] 内以外で [文字] で区切られた文字列を分割するにはどうすればよいですか?も参照してください。

于 2012-06-27T14:26:29.580 に答える
2

はい、これを行うことができますが、それぞれの状況で新しい正規表現を発明する必要があります。この場合、特効薬はありません。

アンダースコアでスペースを変更する必要がありますが、すべてではなく、引用符で区切られた部分文字列内にあるスペースのみを変更する必要があります。ルック アヘッド アサーションとルック ビハインド アサーションでチェックする最後の条件ですが、これらのチェックを定式化するのはそれほど簡単ではありません。

例えば:

$ perl -pe 's/(?<=")(\S+)\s+(?=.*")/$1_/g;'
a b "c d" e f
a b "c_d" e f

しかし、これは完璧とはほど遠いものです。これは、最も簡単な状況で機能します。これは解決策ではなく、単なるアイデアのデモンストレーションです。

于 2012-06-27T14:36:13.783 に答える
1

あなたは試すことができます:

   $str =~ s{"([^"]+)"}{do{(local$_=$1)=~y/ /_/;$_}}eg;

または、読みやすくするために:

   $str =~ s/
             "([^"]+)"     # all inside double quotes to $1
            / do{          # start a do block
                 local $_ = $1; # get a copy from $1
                 y| |_|;        # transliterate ' ' to '_'
                 $_             # return string from block
                }          # end the do block
            /xeg;

よろしく

rbo

于 2012-06-27T14:47:20.720 に答える