5

Perl の qr{} コンストラクトを使用する場合、どの文字をエスケープする必要があるかを判断するのに苦労しています

無数の通常エスケープ文字 (#*.>:[]) を含み、別のプリコンパイル済み正規表現も含む、複数行のプリコンパイル済み正規表現を作成しようとしています。さらに、テスト目的で可能な限り厳密に一致させる必要があります。

my $output = q{# using defaults found in .config
*
*
Options:
  1. opt1
> 2. opt2
choice[1-2?]: };

my $sc = qr{(>|\s)}smx;
my $re = qr{# using defaults found in .config
*
*
Options:
$sc 1. opt1
$sc 2. opt2
choice[1-2?]: }mx;

if ( $output =~ $re ) {
  print "OK!\n";
}
else {
  print "D'oh!\n";
}

エラー:

Quantifier follows nothing in regex; marked by <-- HERE in m/# using defaults found in .config
* <-- HERE 
*
Options:
(?msx-i:(>|\s)) 1. opt1
(?msx-i:(>|\s)) 2. opt2
choice[1-2?]: / at ./so.pl line 14.

アスタリスクをエスケープしようとすると、一致に失敗します (D'oh 出力)。他の厄介な文字をエスケープしようとしても、一致は失敗します。エスケープするもののさまざまな組み合わせを試し続けることもできますが、ここには多くのバリエーションがあり、誰かが洞察を提供できることを望んでいます.

4

3 に答える 3

14

qr //の区切り文字をエスケープする必要があり、リテラルとして使用する正規表現メタ文字をエスケープする必要があります。それらをリテラル*にしたい場合は、*が正規表現の数量詞であるため、それらをエスケープする必要があります。

ここでの問題は、追加したさまざまな正規表現フラグです。文字列の先頭または末尾のアンカー(^、$)を使用しないため、/mは何もしません。ワイルドカードを使用しないため、/sは何もしません。メタ文字。/ xは、正規表現内のすべての空白を無意味にし、#を含むその行を正規表現コメントに変換します。

これは、正規表現フラグが削除され、適切なものがエスケープされた状態で、必要なものです。

my $sc = qr{(>|\s)};

my $re = qr{# using defaults found in \.config
\*
\*
Options:
$sc 1\. opt1
$sc 2\. opt2
choice\[1-2\?]: };

ダミアン・コンウェイは、Perl Best Practicesの人々に、これらのオプションを常に正規表現に配置するように指示していますが、彼が間違っている理由がわかります。あなたは彼らが何をしたいのかを知りたいときにだけそれらを追加すべきであり、あなたは彼らが何をしているのかを知っているときにだけ物事を追加すべきです。:)/xを使用する場合は次のようにします。リテラルの空白をエスケープする必要があり、行末を何らかの方法で示す必要があり、リテラルの#文字をエスケープする必要があります。以前は読み取り可能だったものが、今では混乱しています。

私の$sc= qr {(> | \ s)};
私の$eol= qr {[\ r \ n] +};

my $ re = qr {\#\ s + using \ s + defaults \ s + found \ s + in \ s + \ .config $ eol
\ * $ eol
\ * $ eol
オプション:$ eol
$ sc \ s +1\。\ s + opt1 $ eol
$ sc \ s +2\。\ s + opt2 $ eol
選択\[1-2\?]:\ s +
}バツ;

if($ output =〜$ re){
  印刷"OK!\ n";
}
そうしないと {
  印刷"D'oh!\ n";
}
于 2008-11-14T19:56:51.280 に答える
7

本当に欲しいのはExpectのように聞こえますが、最もすぐに探しているのは、正規表現に対して特別な意味を持つすべての文字をエスケープするquotemeta演算子です。

質問に直接答えるには(ただし、引用符で囲まれていない文字(この場合})に加えて、少なくともエスケープする必要があります。.[$()|*+?{\

于 2008-11-14T20:05:23.573 に答える
2

ブライアンが言ったように、区切り文字と正規表現のメタ文字をエスケープする必要があります。qr//x(あなたが)を使用するときは、空白文字と#(コメントマーカー)もエスケープする必要があることに注意してください。ここでは実際には使いたくないでしょう/x。安全を確保したい場合は、英数字以外の文字をエスケープできます

于 2008-11-14T20:08:55.220 に答える