Как искать часть строки в массиве?
Я хочу найти, является ли полная строка или часть строки частью массива. Как это может быть достигнуто в PHP?
Кроме того, как я могу использовать метафон в нем?
Пример:
array1={'India','USA','China'};
array2={'India is in east','United States of America is USA','Made in China'}
Если я ищу array1
в array2
, затем:
"Индия" должна соответствовать "Индия на востоке" и аналогично для США и Китая.
3 ответа
$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";
}
}
}
$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 сложнее. Вам нужно будет определить, из чего состоит матч. Один из способов сделать это - использовать расстояние Левенштейна между результатами метафона для двух сравниваемых значений.
Обновление: См . Решение @Andrea для более разумного сравнения Metaphone по каждому слову.
Вот грубый пример:
$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 );
}
}
}
... но это требует работы. Это производит дубликаты, если порог слишком высок. Вы можете предпочесть провести матч в два прохода. Один для поиска простых совпадений, как в моем первом примере кода, а затем другой для сопоставления с метафоном, если первый не возвращает совпадений.
Случай с метафоном может также следовать той же структуре, предложенной Майком для строгого случая.
Я не думаю, что необходима дополнительная функция подобия, потому что цель метафона должна состоять в том, чтобы дать нам ключ, который является общим для слов, которые звучат одинаково.
$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',
),
)