10

PHPで2つの文字列の一致する部分を見つける簡単な方法を探しています(特にURIのコンテキストで)

たとえば、次の 2 つの文字列について考えてみます。

http://2.2.2.2/~machinehost/deployment_folder/

/~マシンホスト/配置フォルダー/ユーザー/ボブ/設定

必要なのは、これら 2 つの文字列の一致する部分を 2 番目の文字列から切り取ることです。結果は次のようになります。

ユーザー/ボブ/設定

最初の文字列をプレフィックスとして追加する前に、絶対 URI を形成します。

任意の 2 つの文字列を比較してその中の部分文字列を一致させる簡単な方法 (PHP) はありますか?

編集:指摘したように、両方の文字列に共通する最長一致部分文字列を意味しました

4

5 に答える 5

2

$a文字列がそれぞれとであると仮定すると$b、これを使用できます。

$a = 'http://2.2.2.2/~machinehost/deployment_folder/';
$b = '/~machinehost/deployment_folder/users/bob/settings';

$len_a = strlen($a);
$len_b = strlen($b);

for ($p = max(0, $len_a - $len_b); $p < $len_b; $p++)
    if (substr($a, $len_a - ($len_b - $p)) == substr($b, 0, $len_b - $p))
        break;

$result = $a.substr($b, $len_b - $p);

echo $result;

この結果はhttp://2.2.2.2/~machinehost/deployment_folder/users/bob/settingsです。

于 2010-11-25T23:56:19.010 に答える
0

あなたのリクエストを完全に理解できるかどうかはわかりませんが、アイデアは次のとおりです。

A を URL、B を「/~machinehost/deployment_folder/users/bob/settings」とする

  • A で B を検索 -> インデックス i を取得します (ここで、i は A の B の最初の / の位置です)
  • l = 長さ (A) とする
  • B の最後の部分 (/users/bob/settings) を取得するには、B を (li) から長さ (B) にカットする必要があります。

まだテストしていませんが、本当に必要な場合は、この素晴らしい (皮肉な) ソリューションを機能させることができます。

次のような正規表現で可能な場合があることに注意してください

$pattern = "$B(.*?)"
$res = array();
preg_match_all($pattern, $A, $res);

編集:あなたの最後のコメントは私の応答を無効にすると思います。しかし、あなたが望むのは部分文字列を見つけることです。したがって、最初に、{2, length(B)} の i に対して A で B[1:i] を見つけようとする重いアルゴリズムから始めて、次に動的プログラミングを使用することができます。

于 2010-11-25T23:55:48.443 に答える
0

あなたの要件に合わせてすぐに使えるコードではないようです。それでは、簡単な方法を探してみましょう。

この演習では、2 つの方法を使用しました。1 つは最長の一致を見つけるためのもので、もう 1 つは一致部分を切り取るためのものです。

FindLongestMatch ()メソッドは、パスを分解し、1 つ 1 つの一致、つまり最も長い一致 (配列なし、並べ替えなし) を保持しながら、他のパスで一致するものを 1 つずつ探します。RemoveLongestMatch ()メソッドは、見つかった最長一致位置の後にサフィックスまたは「残り」を取ります。

ここに完全なソースコードがあります:

<?php

function FindLongestMatch($relativePath, $absolutePath)
{
    static $_separator = '/';
    $splitted = array_reverse(explode($_separator, $absolutePath));

    foreach ($splitted as &$value)
    {
        $matchTest = $value.$_separator.$match;
        if(IsSubstring($relativePath, $matchTest))
            $match = $matchTest;

        if (!empty($value) && IsNewMatchLonger($match, $longestMatch))
            $longestMatch = $match;
    }

    return $longestMatch;
}

//Removes from the first string the longest match.
function RemoveLongestMatch($relativePath, $absolutePath)
{
    $match = findLongestMatch($relativePath, $absolutePath);
    $positionFound = strpos($relativePath, $match);     
    $suffix = substr($relativePath, $positionFound + strlen($match));

    return $suffix;
}

function IsNewMatchLonger($match, $longestMatch)
{
    return strlen($match) > strlen($longestMatch);
}

function IsSubstring($string, $subString)
{
    return strpos($string, $subString) > 0;
}

これは、テスト ケースの代表的なサブセットです。

//TEST CASES
echo "<br>-----------------------------------------------------------"; 
echo "<br>".$absolutePath = 'http://2.2.2.2/~machinehost/deployment_folder/';
echo "<br>".$relativePath = '/~machinehost/deployment_folder/users/bob/settings';
echo "<br>Longest match: ".findLongestMatch($relativePath, $absolutePath);
echo "<br>Suffix: ".removeLongestMatch($relativePath, $absolutePath);

echo "<br>-----------------------------------------------------------"; 
echo "<br>".$absolutePath = 'http://1.1.1.1/root/~machinehost/deployment_folder/';
echo "<br>".$relativePath = '/root/~machinehost/deployment_folder/users/bob/settings';
echo "<br>Longest match: ".findLongestMatch($relativePath, $absolutePath);
echo "<br>Suffix: ".removeLongestMatch($relativePath, $absolutePath);

echo "<br>-----------------------------------------------------------"; 
echo "<br>".$absolutePath = 'http://2.2.2.2/~machinehost/deployment_folder/users/';
echo "<br>".$relativePath = '/~machinehost/deployment_folder/users/bob/settings';
echo "<br>Longest match: ".findLongestMatch($relativePath, $absolutePath);
echo "<br>Suffix: ".removeLongestMatch($relativePath, $absolutePath);

echo "<br>-----------------------------------------------------------"; 
echo "<br>".$absolutePath = 'http://3.3.3.3/~machinehost/~machinehost/subDirectory/deployment_folder/';
echo "<br>".$relativePath = '/~machinehost/subDirectory/deployment_folderX/users/bob/settings';
echo "<br>Longest match: ".findLongestMatch($relativePath, $absolutePath);
echo "<br>Suffix: ".removeLongestMatch($relativePath, $absolutePath);

以前のテスト ケースを実行すると、次の出力が得られます。

http://2.2.2.2/~machinehost/deployment_folder/
/~machinehost/deployment_folder/users/bob/settings
Longuest match: ~machinehost/deployment_folder/
Suffix: users/bob/settings

http://1.1.1.1/root/~machinehost/deployment_folder/
/root/~machinehost/deployment_folder/users/bob/settings
Longuest match: root/~machinehost/deployment_folder/
Suffix: users/bob/settings

http://2.2.2.2/~machinehost/deployment_folder/users/
/~machinehost/deployment_folder/users/bob/settings
Longuest match: ~machinehost/deployment_folder/users/
Suffix: bob/settings

http://3.3.3.3/~machinehost/~machinehost/subDirectory/deployment_folder/
/~machinehost/subDirectory/deployment_folderX/users/bob/settings
Longuest match: ~machinehost/subDirectory/
Suffix: deployment_folderX/users/bob/settings

このコードのアイデアを取り入れて、現在のプロジェクトに役立つものに変えることができるかもしれません。それがあなたにとってもうまくいったかどうか教えてください。ちなみにoreXさんの回答も良さそうです。

于 2010-11-26T03:55:17.287 に答える
-1

これを試して。

http://pastebin.com/GqS3UiPD

于 2010-11-26T00:12:28.857 に答える