3

申し訳ありませんが、「ProgrammingPerl」の本からのかなり複雑なスニペットを理解するためにもう一度助けが必要です。ここにあります(太字でマークされている私にはわかりにくいものです):

パターンは二重引用符で囲まれた文字列のように解析され、変数の補間(区切り文字として一重引用符を使用しない限り)やバックスラッシュエスケープで示される特殊文字など、通常の二重引用符の規則はすべて機能します。これらは、文字列が正規表現として解釈される前に適用されます(これは、文字列が複数回処理されるPerl言語の数少ない場所の1つです)。..。

この2パス解析の別の結果は、通常のPerlトークン作成者が、通常の文字列の終了区切り文字を探しているかのように、正規表現の終わりを最初に見つけることです。文字列の終わりを検出した後(および変数の補間を実行した後)にのみ、パターンは正規表現として扱われます。特に、これは、正規表現構造内のパターンの終了区切り文字を「非表示」にできないことを意味します(括弧で囲まれた文字クラスや、まだ説明していない正規表現コメントなど)。Perlはどこにいても区切り文字を確認し、その時点でパターンを終了します。

まず、前に述べたように、なぜそれが見てOnly after it has found the end of the stringいなかったと言わthe end of the regular expressionれるのですか?

第二に、それはどういう意味you can’t “hide” the terminating delimiter of a pattern inside a regex constructですか?終了区切り文字を非表示にできないのに、正規表現または補間変数(がなくても)/のどこにでも配置できるのはなぜですか。/A\/C/\

my $s = 'A/';
my $p = 'A/C';
say $p =~ /$s/;

出力1

質問を書いたり読み直したりしているときに、このスニペットは正規表現の区切り文字として一重引用符を使用することを示していると思いましたが、すべてが非常にまとまりがあるように見えます。私の仮定は正しいですか?

感謝します。

4

2 に答える 2

7

「正規表現の終わり」ではなく「文字列の終わり」と表示されます。これは、その時点で正規表現が単なる文字列であるかのように扱われるためです。

これは機能しないと言おうとしています。

/foo[-/_]/

通常の正規表現メタ文字は内部で特別ではありませんが[]、Perlは正規表現を未/foo[-/終了のクラスと見なして文句を言います。

Perlは正規表現を読み取るときに正規表現を解析しないと言おうとしています。最初に、引用符で囲まれた文字列であるかのようにソースコード内の正規表現の終わりを検出するため、特殊文字は。のみです\。次に、変数を補間します。 次に、結果を正規表現として解析します。

\通常の文字列で機能するため、で終了区切り文字を非表示にすることができます。区切り文字が見つかった後に補間が行われるため、補間された変数内で区切り文字を非表示にすることができます。ブラケット区切り文字({ }または[ ])を使用する場合、そのように機能するため、一致する区切り文字のペアを正規表現内にネストできq{}ます。ただし、他の正規表現構造内に非表示にすることはできません。

于 2012-07-31T16:57:59.423 に答える
5

一致させたいとしましょう*。あなたが使用します

m/\*/

*しかし、区切り文字として使用した場合はどうなりますか?以下は機能しません。

m*\**

それはとして解釈されるので

m/*/

次のように:

$ perl -e'm*\**'
Quantifier follows nothing in regex; marked by <-- HERE in m/* <-- HERE / at -e line 1.

文字列リテラルを取得します

"a\"b"

文字列を生成します

a"b

同様に、一致演算子

m*a\*b*

正規表現パターンを生成します

a*b

リテラルと一致させたい場合は*、他の手段を使用する必要があります。言い換えると。

m*a\*b*      ===  m/a*b/       matches pattern a*b
m*a\x{2A}b*  ===  m/a\*b/      matches pattern a\*b
于 2012-07-31T17:00:41.840 に答える