Элементы массива в строковом PHP: Как я могу напечатать_r соответствующие элементы в порядке строки?

#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
)
  

Демонстрация на 3v4l.org

Обратите внимание, что существует проблема с использованием 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
(
)
  

Демонстрация на 3v4l.org

Вы можете еще больше упростить это, используя 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;
}
  

Демонстрация на 3v4l.org

Комментарии:

1. preg_match_all также может быть применен здесь. в общем, preg_match будет более полезным, чем strpos, но это разные животные, так что это то, с чем вам удобно

2. @ChrisRichardson абсолютно — я пытался максимально приблизить ответ к коду OP. Однако я сделаю замечание о проблеме, касающейся границ слов.

3. @Nick это работает очень хорошо ! На самом деле, первый вариант идеально соответствует тому, чего я хотел достичь. Спасибо за другие варианты! Они определенно помогут в ближайшем будущем!!

Ответ №2:

Я могу посоветовать следующий подход:

  1. разбить строку на массив слов

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

Вы можете попробовать живой PHP-код на PHPize.online

Ответ №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. Как насчет случая, когда одно слово массива появляется больше, когда один раз в строке? Другое слово для ввода массива — это вложенное слово в строке?