-2

ファイルを含むネストされたディレクトリのように、それぞれに名前が含まれるネストされたハッシュのツリーがあります。実行時に外部から提供された正規表現を取得した場合 (これは分析したくありません)、どのサブツリーで一致を探すかをどのように見つけることができますか。一致するパスは、次の形式である可能性があります

"$x{name}/$x{subdir}{name}/$x{subdir}{subdir}{name}"

ただし、何千ものハッシュが存在する可能性があるため、これらの両方が部分的に一致する場合にのみ試してみたいと思います。

"$x{name}"
"$x{name}/$x{subdir}{name}"

/\G.../gまたはさらに良いことに、最初の部分が一致する場合は、正規表現が別の場所から 1 つにまとめられていることを除いて、2 番目の部分を直接続行し、次に 3 番目の部分を続行しようとします。また、部分的に一致する他のすべてのサブディレクトリも調べるには、バックトラックが必要です。

PCRE g_match_info_is_partial_matchはまさに私が探しているものに聞こえますが、その名前に「Perl」が含まれているにもかかわらず、5.18 ソースでさえこれが含まれていないようです。そして、実際には 5.8.0 との下位互換性が必要です。

この質問の背景は、正規表現構文をmakeppに導入することです。基本的にはパターンに対してこれを行いますが、単純な構文のため、それは簡単です。見つかったファイルをキャッシュし、より多くのファイルが表示されると処理できることに注意してください。これにより、ルールの出力もツリーに配置されるため、makepp は後でビルドされる可能性のあるファイルに一致させることができます。

4

1 に答える 1

0

Perl 正規表現と PCRE は互いに影響を与え合っていますが、実際には互換性がなく、まったく同じではありません。Perl はカスタム正規表現エンジンを使用します。

正規表現が一致するか、一致しないかのいずれかです。正規表現が失敗した場合、正規表現が位置を報告するような方法で書かれている場合を除いて、一致がどこで失敗したかを知ることは不可能です。

唯一の実行可能な解決策は、レベルごとに 1 つの正規表現のリストを要求することです。

そうしないと、部分一致も機能するような方法で正規表現を作成するようにユーザーに要求できます。この場合、正規表現qr|foo/bar\.txt$|を書き直す必要があります

qr|\A /                # anchor at start
  (?: [^/]*/       )*  # match as many directories as neccessary
  (?: foo/bar\.txt )?  # maybe match an ending foo/bar.txt
\z|x                   # anchor at end

例:

for ("/a/", "/a/b/", "/a/b/foo/", "/a/b/foo/bar.txt", "/a/b/foo/baz.txt", "/a/bar.txt") {
  say qq("$_" -- ), /$regex/ ? "matches" : "doesn't match";
}

出力:

"/a/" -- matches
"/a/b/" -- matches
"/a/b/foo/" -- matches
"/a/b/foo/bar.txt" -- matches
"/a/b/foo/baz.txt" -- doesn't match
"/a/bar.txt" -- doesn't match

明らかに、これによってこの正規表現の検索スペースが減ることはありません。

アプリケーションに適した方法でこれをスピンできる場合があります。アプリが提供する保証に応じて、元の正規表現を「常に」一致するものに自動的に変換できます。

于 2013-08-06T23:33:32.477 に答える