#php #arrays
#php #массивы
Вопрос:
Я пытаюсь идентифицировать несколько Array
элементов, присутствующих в строке. Я хотел бы напечатать_r соответствующие элементы в виде массива в порядке строки.
Пример и пробная версия:
$string = "hello my dear, how are you doing today ?";
$array = array('are', 'today','hello','bonjour','Holà', 'Wassup');
$result = array('hello','are','today');
function match($array , $string ){
foreach ($array as $a) {
if (strpos($string ,$a) == true) {
return $a;
}
}
}
Функция возвращает следующую ошибку :
strpos(): needle не является строкой или целым числом
Есть идеи??
Большое спасибо из Франции!
Комментарии:
1.
var_dump($a)
что дает?2. strpos возвращает целое число (позицию) и не true, если найдено, и false, если не найдено
3. исследование w3schools.com/php/func_string_strpos.asp
Ответ №1:
Основная проблема с вашим кодом заключается в том, что вы return
, как только находите одно совпадение, вместо того, чтобы создавать массив из всех совпадающих строк. Что касается возврата строк в том порядке, в котором они встречаются в строке, вы можете использовать возвращаемое значение из strpos
в качестве ключа массива, а затем ksort
результирующий массив перед его возвратом:
$string = "hello my dear, how are you doing today ?";
$array = array('are', 'today','hello','bonjour','Holà', 'Wassup');
function match($array , $string ) {
$result = [];
foreach ($array as $a) {
if (($pos = strpos($string, $a)) !== false) {
$result[$pos] = $a;
}
}
ksort($result);
return array_values($result);
}
print_r(match($array, $string));
Вывод:
Array
(
[0] => hello
[1] => are
[2] => today
)
Обратите внимание, что существует проблема с использованием strpos
в том, что он не учитывает, является ли совпадение полным словом или нет. Так, например, match(['are'], 'hare')
вернет ['are']
. Вы можете обойти это, используя preg_match
вместо strpos
и окружая строку поиска b
(граница слова):
function match($array , $string ) {
$result = [];
foreach ($array as $a) {
if (preg_match("~b$ab~", $string, $matches, PREG_OFFSET_CAPTURE)) {
$result[$matches[0][1]] = $a;
}
}
ksort($result);
return array_values($result);
}
Пример использования:
print_r(match($array, $string));
print_r(match(['are'], 'hare'));
Вывод:
Array
(
[0] => hello
[1] => are
[2] => today
)
Array
(
)
Вы можете еще больше упростить это, используя preg_match_all
и объединяя все элементы $array
в чередование регулярных выражений:
function match($array , $string ) {
$result = [];
foreach ($array as $a) {
if (preg_match_all('~b' . implode('b|b', $array) . 'b~', $string, $matches)) {
$result = $matches[0];
}
}
return $result;
}
Комментарии:
1. preg_match_all также может быть применен здесь. в общем, preg_match будет более полезным, чем strpos, но это разные животные, так что это то, с чем вам удобно
2. @ChrisRichardson абсолютно — я пытался максимально приблизить ответ к коду OP. Однако я сделаю замечание о проблеме, касающейся границ слов.
3. @Nick это работает очень хорошо ! На самом деле, первый вариант идеально соответствует тому, чего я хотел достичь. Спасибо за другие варианты! Они определенно помогут в ближайшем будущем!!
Ответ №2:
Я могу посоветовать следующий подход:
-
разбить строку на массив слов
-
сравните 2 массива в цикле»
<?php $string = "hello my dear, how are you doing today ?"; $array = array('are', 'today','hello','bonjour','Holà', 'Wassup'); function match($array , $string ) { $result = []; $string_to_arr = explode(' ', $string); foreach ($string_to_arr as $s) { if (in_array($s, $array)) { array_push($result, $s); } } return $result; } print_r(match($array , $string ));
Ответ №3:
Вы можете разделить исходную строку на массив слов, а затем пересечь ее с вашим списком слов.
<?php
$string = "hello my dear, how are you doing today ?";
$array = array('are', 'today','hello','bonjour','Holà', 'Wassup');
$result = array('hello','are','today');
$matched =
array_values(
array_intersect(
str_word_count($string, 1),
$array
)
);
var_dump($result === $matched);
var_export($matched);
Вывод:
bool(true)
array (
0 => 'hello',
1 => 'are',
2 => 'today',
)
Вы могли бы поменять str_word_count($string, 1)
на preg_split('/b/', $string)
.
Однако приведенное выше значение чувствительно к регистру.
Вы могли бы заменить array_intersect
на array_uintersect
с помощью сравнения по регистру.
array_uintersect(str_word_count($string, 1), $array, 'strcasecmp')
Для сравнения многобайтовых регистров вам, вероятно, лучше использовать preg_match
маршрут с соответствующими флагами или другую функцию сравнения.
Ответ №4:
мой первоначальный ответ был банальным, просто удалите == true
Комментарии:
1. это правильно. проблема не в том, что я не занимаюсь обучением, если параметр состояния включает результат функции, любой ненулевой результат будет передан в возвращаемую функцию
2. Как насчет случая, когда одно слово массива появляется больше, когда один раз в строке? Другое слово для ввода массива — это вложенное слово в строке?