UNIXファイルパスの最も正しい正規表現(regex)は何ですか?
たとえば、次のようなものを検出するには:
/usr/lib/libgccpp.so.1.0.2
ほとんどのファイルに一致する正規表現を作成するのは非常に簡単ですが、エスケープされた空白シーケンスを検出できるものや、UNIXのファイルパスに通常は見られない珍しい文字など、最適なものは何ですか。
また、ファイルパスの正規表現を提供するいくつかの異なるプログラミング言語のライブラリ関数はありますか?
パスの識別に誤検知を気にしない場合は、パスにNUL
文字が含まれていないことを確認するだけで十分です。それ以外はすべて許可されます(特に、_/
_は名前区切り文字です)。適切な方法は、適切なファイルを使用して、指定されたパスを解決することですIO function(eg File.exists()
、 File.getCanonicalFile()
(Javaの場合)。
長い答え:
これはオペレーティングシステムとファイルシステムの両方に依存しています。たとえば、 ファイルシステムのウィキペディア比較 は、ファイルシステムによって課される制限のほかに、
MS-DOS、Microsoft Windows、およびOS/2では、ファイル名およびディレクトリ名across all filesystemsで_
\ / : ? * " > < |
_およびNUL
を使用できません。 UnicesとLinuxは、ファイル名とディレクトリ名across all filesystemsで_/
_およびNUL
の文字を許可しません。
Windowsでは、次の 予約済みデバイス名 もファイル名として許可されていません。
_CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5,
COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4,
LPT5, LPT6, LPT7, LPT8, LPT9
_
すべてのUNIXパスに一致する正規表現は次のとおりです:[^\0] +
つまり、NULではない1つ以上の文字です。
この質問に回答した他の人にとって、作成しているプログラムでエスケープ文字がどのように機能するかに応じて、一部のアプリケーションでは少し異なる正規表現が必要になることに注意することが重要です。たとえば、シェルを作成していて、コマンドをスペースやその他の特殊文字で区切る場合、それらの文字がエスケープされている場合は、正規表現を変更して特殊文字を含む単語のみを含める必要があります。
したがって、たとえば、有効なパスは次のようになります。
/usr/bin/program\with\space
とは対照的に
/usr/bin/program with space
「/ usr/bin/program」を引数「with」と「space」で参照します
上記の例の正規表現は「([^\0]\| \\)*」のようになります。
私が取り組んでいる正規表現は(「読みやすさ」のために改行で区切られています):
"\(#どちらか [^\0!$`&*()+]#通常の(特殊でない)文字 \|#または \\\(\| \!|\$ |\`| \&|\* | \(| \)|\+ \)#エスケープされた特殊文字 \)\ +"#繰り返し> = 1回
に変換します
「\([^\0!$ `&*()+]\| \\\(\ | \!|\$ | \` | \&|\* | \(| \)|\+ \)\)\ + "
独自の特定の正規表現を作成するのも比較的簡単です。
^(/)?([^/\0]+(/)?)+$
extX、reiserfsのようなファイルシステムで有効なすべてのパスを受け入れます。
NULまたは二重(またはそれ以上)のスラッシュを含むパス名のみを破棄します。 Unix仕様によると、その他すべては合法であるはずです(私もこの結果に驚いています)。
これに対する正規表現チェックがシステム全体でどれほど一般的であるかはわかりませんが、ほとんどのプログラミング言語(特にクロスプラットフォームのもの)は、このようなことを考慮に入れる「ファイルの存在」チェックを提供します
好奇心から、これらのパスはどこに入力されていますか?パスの個々の部分をチェックする必要がない点まで、それをより大きな退行に制御できますか?たとえば、ファイル選択ダイアログを使用していますか?
すでにここで回答されている質問: https://stackoverflow.com/a/42036026/1951947