2

文字列全体または文字列の一部が配列の一部であるかどうかを検索したいと思います。これはPHPでどのように達成できますか?

また、メタフォンを使用するにはどうすればよいですか?

例:

array1={'India','USA','China'};
array2={'India is in east','United States of America is USA','Made in China'}

で検索するarray1array2、次のようになります。

「インド」は「インドは東にある」と一致する必要があり、米国と中国も同様です。

4

3 に答える 3

4
$array1 = array('India','USA','China');
$array2 = array('India is in east','United States of America is USA','Made in China');
$found = array();

foreach ($array1 as $key => $value) {
    // Thanks to @Andrea for this suggestion:
    $found[$value] = preg_grep("/$value/", $array2);
    // Alternative:
    //$found = $found + preg_grep("/$value/", $array2);
}

print_r($found);

結果:

Array
(
    [0] => India is in east
    [1] => United States of America is USA
    [2] => Made in China
)

Metaphoneの使用は注意が必要です。何が一致を構成するかを決定する必要があります。これを行う1つの方法は、比較する2つの値のメタフォン結果間のレーベンシュタイン距離を使用することです。

更新:より賢明な単語ごとのメタフォンの比較については、@Andreaのソリューションを参照してください。

大まかな例を次に示します。

$meta1 = array_map(
    create_function( '$v', 'return array(metaphone($v) => $v);' ),
    $array1
);

$meta2 = array_map(
    create_function( '$v', 'return array(metaphone($v) => $v);' ),
    $array2
);

$threshold = 3;

foreach ($meta2 as $key2 => $value2) {

    $k2 = key($value2);
    $v2 = $value2[$k2];

    foreach ($meta1 as $key1 => $value1) {

        $k1  = key($value1);
        $v1  = $value1[$k1];
        $lev = levenshtein($k2, $k1);

        if( strpos($v2, $v1) !== false || levenshtein($k2, $k1) <= $threshold ) {
            array_push( $found, $v2 );
        }
    }
}

...しかし、それは作業が必要です。しきい値が高すぎる場合、重複が生成されます。2つのパスで試合を実行することをお勧めします。1つは私の最初のコード例のように単純な一致を見つけるためのもので、もう1つは最初に一致が返されない場合にMetaphoneと一致するものです。

于 2011-07-19T10:43:14.150 に答える
1

メタフォンの場合も、厳密な場合にマイクが提案したのと同じ構造に従うことができます。

メタフォンの目的は、同じように聞こえる単語に共通するキーを提供することであるため、追加の類似度関数は必要ないと思います。

$array1 = array('India','USA','China');
$array2 = array(
    'Indiuh is in east',
    'United States of America is USA',
    'Gandhi was born in India',
    'Made in China'
);
$found = array();
foreach ($array1 as $key => $value) {
    $found[$value] = preg_grep('/\b'.$value.'\b/i', $array2);
}

var_export($found);

echo "\n\n";

function meta( $sentence )
{
    return implode(' ', array_map('metaphone', explode(' ', $sentence)));
}

$array2meta = array_map('meta', $array2);
foreach ($array1 as $key => $value) {
    $valuemeta = meta($value);
    $foundmeta[$value] = preg_grep('/\b'.$valuemeta.'\b/', $array2meta);
    $foundmeta[$value] = array_intersect_key($array2, $foundmeta[$value]);
}

var_export($foundmeta);

上記のコードは次のように出力されます。

array (
  'India' => 
  array (
    2 => 'Gandhi was born in India',
  ),
  'USA' => 
  array (
    1 => 'United States of America is USA',
  ),
  'China' => 
  array (
    3 => 'Made in China',
  ),
)

array (
  'India' => 
  array (
    0 => 'Indiuh is in east',
    2 => 'Gandhi was born in India',
  ),
  'USA' => 
  array (
    1 => 'United States of America is USA',
  ),
  'China' => 
  array (
    3 => 'Made in China',
  ),
)
于 2011-07-19T13:29:02.993 に答える
0
$a1 = array('India','USA','China');
$a2 = array('India is in east','United States of America is USA','Made in China');


foreach ( $a2 as $a )
{
  foreach( $a1 as $b  )
  {
    if ( strpos( $a, $b ) > -1 )
    {
      echo $a . " contains " . $b . "\n";
    }
  }
}
于 2011-07-19T10:01:55.240 に答える