У меня есть функция в php, которую я хотел бы выполнить простой поиск в строке, используя kw в качестве поисковой фразы и возвращать true, если найден.
Это то, что у меня есть сейчас:
for($i=0; $i<count($search_strings); $i++){ $pos = strpos($search_strings[$i], $kw_to_search_for); }
Это прекрасно работает и действительно находит ключевое слово внутри строки, которую нужно искать, но проблема в том, что strpos не соответствует точным фразам или словам.
Например, поиск «HP» вернет true, если слово «PHP» было в строке.
Я знаю о preg_split и регулярных выражениях, которые могут использоваться для точных совпадений, но в моем случае я не знаю, какое ключевое слово для каждого поиска, потому что ключевое слово вводится пользователем .
Таким образом, ключевое слово может быть «hot-rods», «AC / DC», «Title: Subject» и т. Д. И т. Д. Это означает, что я не могу разбить слова и проверить их отдельно, потому что мне придется использовать какой-то динамический шаблон для регулярного выражения.
Если кто-нибудь узнает о хорошем решении, я бы очень это оценил.
Я имею в виду, в основном, я хочу только точные совпадения, поэтому, если KW является «Prof», тогда это вернет true, если совпадение в искомой строке «Prof» и не имеет других окружающих ее символов.
Например, «Профессионал» должен быть ЛОЖНЫМ.
Вы можете использовать границы слов \b
:
if (preg_match("/\b".preg_quote($kw_to_search_for)."\b/i", $search_strings[$i])) { // found }
Например:
echo preg_match("/\bProfessional\b/i", 'Prof'); // 0 echo preg_match("/\bProf\b/i", 'Prof'); // 1
/i
делает регистр нечувствительным.
В моем случае мне нужно было точно соответствовать professional
когда в предложении существовал professional.bowler
.
Где preg_match('/\bprofessional\b/i', 'Im a professional.bowler');
возвращает int(1)
.
Чтобы решить эту проблему, я прибегал к массивам, чтобы найти точное совпадение слов, используя isset
на клавишах.
Демонстрация
$wordList = array_flip(explode(' ', 'Im a professional.bowler')); var_dump(isset($wordList['professional'])); //false var_dump(isset($wordList['professional.bowler'])); //true
Метод также работает для путей к каталогам, например, при изменении php include_path
, в отличие от использования preg_replace
который был моим конкретным прецедентом.
Демо-версия
$removePath = '/path/to/exist-not' ; $includepath = '.' . PATH_SEPARATOR . '/path/to/exist-not' . PATH_SEPARATOR . '/path/to/exist'; $wordsPath = str_replace(PATH_SEPARATOR, ' ', $includepath); $result = preg_replace('/\b' . preg_quote($removePath, '/'). '\b/i', '', $wordsPath); var_dump(str_replace(' ', PATH_SEPARATOR, $result)); //".:/path/to/exist-not:/path/to/exist" $paths = array_flip(explode(PATH_SEPARATOR, $includepath)); if(isset($paths[$removePath])){ unset($paths[$removePath]); } $includepath = implode(PATH_SEPARATOR, array_flip($paths)); var_dump($includepath); //".:/path/to/exist"
не$removePath = '/path/to/exist-not' ; $includepath = '.' . PATH_SEPARATOR . '/path/to/exist-not' . PATH_SEPARATOR . '/path/to/exist'; $wordsPath = str_replace(PATH_SEPARATOR, ' ', $includepath); $result = preg_replace('/\b' . preg_quote($removePath, '/'). '\b/i', '', $wordsPath); var_dump(str_replace(' ', PATH_SEPARATOR, $result)); //".:/path/to/exist-not:/path/to/exist" $paths = array_flip(explode(PATH_SEPARATOR, $includepath)); if(isset($paths[$removePath])){ unset($paths[$removePath]); } $includepath = implode(PATH_SEPARATOR, array_flip($paths)); var_dump($includepath); //".:/path/to/exist"