ファイル名にダッシュが含まれている場合、Perlに問題があります。

ファイル名にダッシュが含まれている場合、Perlに問題があります。
... | 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]afrom toのすべての小文字と一致しますz (ただし、注2を参照)。

[a\-z][-az]そしてすべて、および[az-]3つの文字のみが一致します。-az

そして@pmqsが答えで指摘したように、[z-a]これは間違った範囲なので、エラーが発生します。

正規表現に1つ以上のダッシュがある角括弧式が含まれている場合は、期待どおりに機能するように変更する必要があります。ほとんどの場合と同様に、使用しているソフトウェアと言語の機能を十分に理解して、必要な/期待するタスクを実行できるようにする必要があります。

man perlre便利な機能やその他の「問題」を含むPerl正規表現の詳細については、リソースを参照してください。このマニュアルページには多くの内容があるので、一度にすべて理解することはできません。必要に応じて検討すると、今後何年にわたってどのように機能するかをより理解することになります。man perlrequickクイックリファレンスとman perlretutチュートリアルも参照してください。man perlrecharclassPerlの文字クラスと角括弧式に関する追加情報。man perlrebackslashPerlのバックスラッシュとエスケープシーケンスに関する追加情報。

man(LinuxディストリビューションまたはUnixにページとして使用できるPerlドキュメントがない場合は、perldoc代わりにrunコマンドを使用してくださいman(例perldoc perlre:)。

Perlは、合計54,000ワードの散文と例からなる5つの主要なマニュアルページが正規表現専用であることを考慮すると(そして2つはおそらくまったく必要ありません:perlregutsPerl正規表現エンジンの仕組みを説明し、perlreapiPerlreのプラグインインターフェイスを説明します)、あなたはこれが複雑なトピックであると推測し始めることができます。そして、あなたは正しいでしょう。


メモ:

1すべての正規表現エンジンが角括弧式内でエスケープ文字をサポートしているわけではありません。 Perlはしかし、ほとんどはそうではありません。たとえば、GNU grepのBRE(デフォルトまたは-G)とERE(-E)はそうではありませんが、GNU grepのperl互換(-P)正規表現はそうです。

2 [[:alpha:]]または通常のASCIIだけでなくUnicodeテキストも処理できるため、通常はアルファベット文字の一致に適しています[[:upper:]]。英数字と同じです。[[:lower:]][[:alnum:]]

関連情報