Например, возможно ли выполнить следующий код?
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
Предположим, у меня есть приведенный выше код, как правильно написать оператор if ($a contains 'are')?
Ответ 1
Вы можете использовать функцию strpos(), которая используется для поиска вхождения одной строки в другую:
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
Обратите внимание, что использование !== false является преднамеренным; strpos() возвращает либо смещение, с которого начинается цепочка символов в строке, либо логическое значение false,если символы не найдены. Поскольку 0 — допустимое смещение, а 0 — это false, мы не можем использовать более простые конструкции, такие как !strpos($a, 'are').
Также теперь в PHP 8 это можно сделать с помощью str_contains:
if (str_contains('How are you', 'are')) {
echo 'true';
}
Ответ 2
Можно использовать регулярные выражения, так как это лучше для сопоставления слов по сравнению с strpos, как упоминалось ранее. Для данного случая можно выполнить следующее:
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
По производительности strpos примерно в три раза быстрее. Когда я сделал один миллион сравнений за один раз, это заняло для preg_match 1,5 секунды, а на strpos ушло 0,5 секунды.
Чтобы искать любую часть строки, а не только слово за словом, я бы рекомендовал использовать регулярное выражение, например:
$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
Знак «i» в конце регулярного выражения изменяет его на нечувствительность к регистру; если вам этого не требуется, просто не указывайте его.
Теперь это может быть довольно проблематично в некоторых случаях, поскольку строка $search иногда может не пройти проверку, как если бы $search был пользовательским вводом.
Regex101 — отличный инструмент для тестирования и просмотра объяснений различных регулярных выражений.
Чтобы объединить оба набора функций в единую многоцелевую функцию (в том числе с возможностью выбора чувствительности к регистру), вы можете использовать что-то вроде этого:
function FindString($needle,$haystack,$i,$word) {
if (strtoupper($word)=="W") {
if (preg_match("/\b{$needle}\b/{$i}", $haystack)) {
return true;
}
} else {
if(preg_match("/{$needle}/{$i}", $haystack)) {
return true;
}
}
return false;
}
Еще одна вещь, о которой следует помнить, это то, что «\b» не будет работать на других языках, кроме английского.
«\b» представляет начало или конец слова (границы слова).
Если вы хотите извлечь символы Unicode, необходимо напрямую определить символы, которые представляют границы слова.
(?<=[\s,.:;"']|^)UNICODE_WORD(?=[\s,.:;"']|$)
Итак, чтобы использовать это в PHP, можно использовать эту функцию:
function contains($str, array $arr) {
// Работает с любыми unicode символами
if (preg_match('/(?<=[\s,.:;"\']|^)'.$word.'(?=[\s,.:;"\']|$)/', $str)) return true;
}
И если вы хотите найти массив слов, можно использовать это:
function arrayContainsWord($str, array $arr) {
foreach ($arr as $word) {
if (preg_match('/(?<=[\s,.:;"\']|^)'.$word.'(?=[\s,.:;"\']|$)/', $str)) return true;
}
return false;
}
Начиная с PHP 8.0.0, можно использовать str_contains:
<?php
if (str_contains('abc', '')) {
echo "Проверка на пустую строку всегда вернет true”;
}
?>
Ответ 3
Вот небольшая служебная функция, которая может пригодиться в подобных ситуациях:
// возвращает true, если $needle является подстрокой $haystack
function contains($needle, $haystack) {
return strpos($haystack, $needle) !== false;
}
Web