正規表現の検索パターンと置換の両方に文字列変数を使用したいと思います。期待される出力は次のようになります。
$ perl -e '$a="abcdeabCde"; $a=~s/b(.)d/_$1$1_/g; print "$a\n"'
a_cc_ea_CC_e
しかし、パターンと置換を変数に移動したとき、$1
評価されませんでした。
$ perl -e '$a="abcdeabCde"; $p="b(.)d"; $r="_\$1\$1_"; $a=~s/$p/$r/g; print "$a\n"'
a_$1$1_ea_$1$1_e
「ee」修飾子を使用すると、エラーが発生します。
$ perl -e '$a="abcdeabCde"; $p="b(.)d"; $r="_\$1\$1_"; $a=~s/$p/$r/gee; print "$a\n"'
Scalar found where operator expected at (eval 1) line 1, near "$1$1"
(Missing operator before $1?)
Bareword found where operator expected at (eval 1) line 1, near "$1_"
(Missing operator before _?)
Scalar found where operator expected at (eval 2) line 1, near "$1$1"
(Missing operator before $1?)
Bareword found where operator expected at (eval 2) line 1, near "$1_"
(Missing operator before _?)
aeae
ここで何が恋しいですか?
どちら$p
と$r
自分で書かれています。私に必要なのはそう、Perlコードに触れることなく交換する複数の同様の正規表現を行うことです$p
し、$r
別のデータファイルである必要があります。このファイルが後でC ++ / pythonコードで使用できることを願っています。$p
との例をいくつか示し$r
ます。
^(.*\D)?((19|18|20)\d\d)年 $1$2<digits>年
^(.*\D)?(0\d)年 $1$2<digits>年
([TKZGD])(\d+)/(\d+)([^\d/]) $1$2<digits>$3<digits>$4
([^/TKZGD\d])(\d+)/(\d+)([^/\d]) $1$3分之$2$4
では$p="b(.)d";
、あなたはリテラル文字で文字列を取得していますb(.)d
。一般に、正規表現パターンは引用符で囲まれた文字列に保存されず、正規表現で期待される意味を持たない場合があります。ただし、最後の注を参照してください。
これがqr演算子の目的です$p = qr/b(.)d/;
。文字列を正規表現として形成します。
交換部品と/ee
については、$r
最初に評価されて、が生成され_$1$1_
、それがコードとして評価されるという問題があります。残念ながら、それは有効なPerlコードではありません。_
裸の単語で、でも$1$1
、それ自体(例えば、有効ではありません$1 . $1
でしょう)。
提供例$r
HAVE $N
Sは、様々な方法でテキストを混合しました。これを解析する1つの方法は$N
、文字列からの順序を維持するリストに他のすべてを抽出することです。次に、それを有効なコードとなる文字列に処理できます。たとえば、
'$1_$2$3other' --> $1 . '_' . $2 . $3 . 'other'
これは、評価できる有効なPerlコードです。
これを分割する部分は、セパレータパターンでのスプリットのキャプチャによって支援されます。
sub repl {
my ($r) = @_;
my @terms = grep { $_ } split /(\$\d)/, $r;
return join '.', map { /^\$/ ? $_ : q(') . $_ . q(') } @terms;
}
$var =~ s/$p/repl($r)/gee;
のパターンでキャプチャ/(...)/
するsplit
と、セパレータはリストの一部として返されます。したがって、これは、元の順序で、すべて(末尾の空白を除く)が保持された、$r
いずれか$N
または他の用語の配列から抽出されます。これには、可能性のある(先頭の)空の文字列が含まれるため、それらを除外する必要があります。
次に、$N
s以外のすべての用語がでラップされる'...'
ため、.
上記の例のように、それらがすべて結合されると、有効なPerl式が取得されます。
次に/ee
、この関数で文字列(上記など)を返し、有効なコードとして評価します。
ここでは/ee
、外部入力での使用の安全性は問題ではないと言われています。それでも、これは覚えておくべきことです。コメントでHåkonHæglandによって提供されたこの投稿を参照してください。議論とともに、それはまた私たちをString :: Substitutionに導きます。その使用法は、この投稿で示されています。これにアプローチする別の方法は、Data :: Mungeからです。replace
の詳細については、この投稿を/ee
参照してください。いくつかの役立つ回答があります。
"b(.)d"
正規表現パターンの使用に関する注意
この場合、parensとdotを使用すると、それらの特別な意味が維持されます。おかげkangshiyinこの初期の言及のために、とのホーコンHæglandそれを主張するため。ただし、これは特殊なケースです。二重引用符で囲まれた文字列は、補間が行われるため、多くのパターンを直接拒否します。たとえば、"\w"
エスケープされただけですw
(認識されないもの)。単一何補間がないよう、引用符は、動作するはずです。それでも、正規表現パターンとして使用することを目的とした文字列qr
は、真の正規表現を取得しているため、を使用して形成するのが最適です。次に、すべての修飾子を使用することもできます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加