... | perl -pe "s/([^$filespec]*)($filespec)/ ...
$filespec
したがって、ほとんどの場合、上記の構造がうまく機能する機能があります。しかし、ファイル名にダッシュがある場合メッセージを受け取りましたInvalid [] range
。
$filespec
これらの解析エラーの影響を受けないファイル名に変数を拡張するにはどうすればよいですか?
答え1
主な仮定 -$filespec
一致させたい文字セット。これはいいえ正規表現。
いくつかのコードを使ってこの問題をシミュレートしましょう。
filespec = 'z-a'
perl -e 'print "MATCH\n" if "DEF" =~ /$filespec/'
use strict;
use warnings;
my $filespec = 'z-a';
print "Match\n" if "DEF" =~ m/[^$filespec]/ ;
走ることができる
Invalid [] range "z-a" in regex; marked by <-- HERE in m/[^z-a <-- HERE ]/ at try line 6.
$filespec
問題は正規表現の拡張ですm/[^z-a]/
。この場合、z-a
文字範囲は無効です。
この問題を解決するには、(少なくとも)-
inをエスケープする必要があります$filespec
。これにより、quotemeta
次のようにトリックを実行できます。
use strict;
use warnings;
my $filespec = quotemeta 'z-a';
print "Match\n" if "DEF" =~ m/[^$filespec]/ ;
出力は次のとおりです
Match
これをパイプコマンドシミュレーションに含めます。 1つ目は失敗したコマンドのバージョンです。
filespec='z-a'
perl -e "print qq[MATCH\n] if 'DEF' =~ /[^$filespec]/"
走る
Invalid [] range "z-a" in regex; marked by <-- HERE in m/[^z-a <-- HERE ]/ at -e line 1.
これは固定バージョンです。
filespec='z-a';
filespec=`perl -e "print quotemeta qq[$filespec]"`
perl -e "print qq[MATCH\n] if 'DEF' =~ /[^$filespec]/"
答え2
括弧内の式のダッシュは、バックスラッシュ1でエスケープされるか、式の最初または最後の文字以外の範囲で処理されます (または、次の最初^
または^
最後の文字のペアで表される場合、式は否定されます)。
例えば
[a-z]
a
from toのすべての小文字と一致しますz
(ただし、注2を参照)。
[a\-z]
、[-az]
そしてすべて、および[az-]
3つの文字のみが一致します。-
a
z
そして@pmqsが答えで指摘したように、[z-a]
これは間違った範囲なので、エラーが発生します。
正規表現に1つ以上のダッシュがある角括弧式が含まれている場合は、期待どおりに機能するように変更する必要があります。ほとんどの場合と同様に、使用しているソフトウェアと言語の機能を十分に理解して、必要な/期待するタスクを実行できるようにする必要があります。
man perlre
便利な機能やその他の「問題」を含むPerl正規表現の詳細については、リソースを参照してください。このマニュアルページには多くの内容があるので、一度にすべて理解することはできません。必要に応じて検討すると、今後何年にわたってどのように機能するかをより理解することになります。man perlrequick
クイックリファレンスとman perlretut
チュートリアルも参照してください。man perlrecharclass
Perlの文字クラスと角括弧式に関する追加情報。man perlrebackslash
Perlのバックスラッシュとエスケープシーケンスに関する追加情報。
man
(LinuxディストリビューションまたはUnixにページとして使用できるPerlドキュメントがない場合は、perldoc
代わりにrunコマンドを使用してくださいman
(例perldoc perlre
:)。
Perlは、合計54,000ワードの散文と例からなる5つの主要なマニュアルページが正規表現専用であることを考慮すると(そして2つはおそらくまったく必要ありません:perlreguts
Perl正規表現エンジンの仕組みを説明し、perlreapi
Perlreのプラグインインターフェイスを説明します)、あなたはこれが複雑なトピックであると推測し始めることができます。そして、あなたは正しいでしょう。
メモ:
1すべての正規表現エンジンが角括弧式内でエスケープ文字をサポートしているわけではありません。 Perlはしかし、ほとんどはそうではありません。たとえば、GNU grepのBRE(デフォルトまたは-G
)とERE(-E
)はそうではありませんが、GNU grepのperl互換(-P
)正規表現はそうです。
2 [[:alpha:]]
または通常のASCIIだけでなくUnicodeテキストも処理できるため、通常はアルファベット文字の一致に適しています[[:upper:]]
。英数字と同じです。[[:lower:]]
[[:alnum:]]