1

入力:

http://foo/bar/baz/../../qux/

望ましい出力:

http://foo/qux/

これは、正規表現を使用して実現できます (誰かがより効率的な代替案を提案できない限り)。

前方参照の場合は、次のように簡単になります。

/\.\.\/[^\/]+/

最初の「/」を後方参照する方法に慣れていませんが(つまり、実行していません/[a-z0-9-_]+\/\.\./)。

私が考えた解決策の 1 つは、strrev正規表現の前方参照 (最初の例) を適用してからstrrev. もっと効率的な方法があると確信していますが。

4

3 に答える 3

0

次のコードを使用できるはずです。

$url = 'http://foo/bar/baz/../../qux/';
$url_parts = parse_url( $url );
$path = $url_parts['path'];
while(strstr($path, '..'))
   $path = preg_replace('~[^/]*/\.{2}/~', '', $path);
$url_parts['path'] = $path;
$canoicalUrl = http_build_url(null, $url_parts);

echo $canoicalUrl;

出力:

http://foo/qux/
于 2013-10-04T15:06:35.810 に答える
0

技術的には、「/path1/path2/../../」のセグメントを「/」に置き換える必要があります。これを行うために必要なのは、「pathx/'^n'../'^n」と一致することです。正規表現ではありません (Context Free Lenguaje) ... しかし、ほとんどの Regex ライブラリはいくつかの非正規言語をサポートしており、(多くの努力を払って) そのような種類の言語を管理できます。

これを解決する簡単な方法は、正規表現にとどまり、'/[^./]+/../' を '' に置き換えて数回繰り返すことです。

それでもワンステップでやるなら、先読みとグループ化が必要ですが、書くのは大変です(慣れていませんが、やってみます)

編集:

たった1つのREGEXで解決策を見つけました...しかし、PCRE Regexを使用する必要があります

([^/.]+/(?1)?\.\./)

次のリンクに基づいてソリューションを作成しました: 正規表現 (PCRE) を使用して a^nb^nc^n (例: "aaabbbccc") に一致させます。

(ドットは最初のセクションで「禁止」されていることに注意してください。必要な場合は、path.1/path.2/ を使用することはできません。これは、最初のセクションで許可する必要がありますが、「../」を禁止する必要があるためです。

このサブ式は、「path1/」のようなパス名を許可するためのものです

[^/.]+/

このサブ式は、二重ドットを許可するためのものです。

\.\./

https://www.debuggex.com/で正規表現をテストでき ます (PCRE モードで設定することを忘れないでください) 。

ここに作業コピーがあります: https://eval.in/52675

于 2013-10-04T14:58:57.747 に答える