2011-07-19 37 views
2

我想要搜索整个字符串还是字符串的一部分是否是数组的一部分。这在PHP中如何实现?如何搜索数组中的一部分字符串?

另外,我怎样才能在其中使用metaphone

例子:

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

如果我在array2搜索array1,则:

'印度' 应符合 '印度在东部',类似的还有美国&中国。

+0

如何约2的foreach或作为变体array_walk – Subdigger

回答

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"; 
    } 
    } 
} 
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 
) 

使用音位是棘手。你将必须确定什么构成匹配。一种方法是使用Methaphone结果之间的Levenshtein距离来比较两个值。

更新:一个更明智的每个字音位比较见@Andrea's解决方案。

这里有一个粗略的例子:

$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); 
     } 
    } 
} 

...但它需要的工作。如果阈值太高,它会产生重复。您可能更愿意以两次传球进行比赛。一个找到简单的匹配,就像在我的第一个代码示例中,然后另一个匹配Metaphone,如果第一个匹配没有返回。

+0

也许是更好$实测值[$值] = preg_grep( “/ $值/”,$数组2) ;所以它一直保持匹配。 – Ando

+0

@Andrea:这可能会奏效,但如果在搜索到的多个元素中发现美国,就有可能覆盖数组键。 – Mike

+0

我在发布之前测试过一个像你这样的$ array2对象,它工作得很好。 – Ando

1

该metaphone案件也可以遵循迈克提出的严格情况下相同的结构。

我不认为需要额外的相似度函数,因为metaphone的目的应该是为我们提供一个与听起来相同的单词相同的密钥。

$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', 
), 
) 
+0

我喜欢在每个词的基础上执行metaphone比较的想法。我不确定OP想要什么,但你的解决方案是有道理的。我不得不介绍Levenshtein函数来处理单词和句子之间的元音结果的差异。 – Mike