Питання Як перевірити, чи містить рядок певне слово?


Розглянемо:

$a = 'How are you?';

if ($a contains 'are')
    echo 'true';

Припустимо, що я маю код вище, яким є правильний спосіб написати твердження if ($a contains 'are')?


2668


походження




Відповіді:


Ви можете скористатись strpos() функція, яка використовується для виявлення виникнення однієї рядка всередині іншого:

$a = 'How are you?';

if (strpos($a, 'are') !== false) {
    echo 'true';
}

Зверніть увагу, що використання !== false навмисне; strpos() повертає або зміщення, за яким починається стрілка голок у стовпці haystack, або логічний false якщо голка не знайдена. Оскільки 0 є дійсним зміщенням, а 0 - «помилковим», ми не можемо використовувати більш прості конструкти, як !strpos($a, 'are').


5448



одна справа, що я знайшов, полягає в тому, що якщо "are" є першим словом, то вищезгаданий код не зможе, тому що він повертає "0", який можна вважати помилковим! Щоб уникнути цього, слід читати, чи (strpos ("x". $ A, 'are')! == false) ..... - Darknight
@Darknight: "0" не вважається "помилковим", коли ви використовуєте! ==. Це розглядається тільки, якщо ви використовуєте! =. - Milan Babuškov
Дуже пізно на вечірку, але будьте обережні з цим. Це також повернеться істинно для рядка "Ви дбаєте?" - DTest
@DTest - ну, звичайно, це повернеться істинно, тому що рядок містить "є". Якщо ви спеціально шукаєте слово ARE, то вам доведеться робити більше перевірок, як, наприклад, перевірити, чи є символ або пробіл перед А та після Е. - jsherk
Дуже гарні коментарі вище! Я ніколи не користуюсь! = Або ==, зрештою! == і === найкращий варіант (на мій погляд) весь аспект розглядається (швидкість, точність тощо). - Melsi


Ви можете використовувати регулярні вирази, то краще для порівняння слів у порівнянні з strpos, як це було згадано іншими користувачами, це також повернеться true для таких рядків, як вартість проїзду, догляд, спостереження тощо. Цього можна просто уникнути в регулярному виразі, використовуючи межі слів.

Простий матч для може виглядати приблизно так:

$a = 'How are you?';

if (preg_match('/\bare\b/',$a))
    echo 'true';

З точки зору продуктивності, strpos є приблизно в три рази швидше і майте на увазі, коли я зробив один мільйон порівнювати відразу, він взяв preg матчі 1,5 секунди, щоб закінчити, і для strpos він зайняв 0,5 секунди.


451



Спасибі за пропозицію, ваш код працює чудово, але я вважаю за краще використовувати функцію strpos. - Charles Yeung
@ Александер.Плутов другим ти даєш мені -1, а не питання? Cmon це займає 2 секунди, щоб Google відповідь google.com/... - Breezer
+1 Це жахливий спосіб пошуку простого рядка, але багато відвідувачів SO шукають будь-який спосіб пошуку будь-якої власної підрядки, і корисно, щоб пропозиція була вихована. Навіть ОП може бути надто спрощеним - хай він знає про його альтернативи. - SamGoody
Технічно питання запитує, як знайти слова не підрядка Це дійсно допомагало мені, тому що я можу використати це з кордонами слова regex. Альтернативи завжди корисні.
+1 для відповіді і -1 на коментар @ plutov.by, оскільки strpos - це лише одна перевірка, тим часом як regexp ви можете перевірити багато слів одночасно ex: preg_match (/ are | you | not /) - albanx


Ось невелика функція корисності, яка корисна в подібних ситуаціях

// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
    return strpos($haystack, $needle) !== false;
}

198



@RobinvanBaalen Насправді це може покращити читання коду. Також передбачається, що низинці будуть мати (дуже) погані відповіді, а не "нейтральні". - Xaqq
Функції @RobinvanBaalen майже визначаються для читабельності (щоб повідомити про те, що ви робите). Порівняйте, що більш читабельно: if ($email->contains("@") && $email->endsWith(".com)) { ... або if (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ... - Brandin
@RobinvanBaalen врешті-решт, правила повинні бути порушені. Інакше люди не зможуть придумати нові винахідливі способи робити речі :). Плюс доведеться визнати, що у мене є проблеми з переходом на розум навколо речей, як на martinfowler.com. Вгадайте, що потрібно робити правильно, це спробувати себе самим і з'ясувати, які підходи є найбільш зручними. - James P.
Інша думка: наявність функції корисності, яку ви можете легко обернути, може допомогти у налагодженні. Також це викликає крик для хороших оптимізаторів, які усувають такі накладні витрати у виробничих сервісах. Тому всі думки мають дійсні моменти. ;) - Tino
Звичайно, це корисно. Ви повинні заохотити це. Що станеться, якщо в PHP 100 з'явиться новий і швидший спосіб знайти розташування рядків? Ви хочете змінити всі ваші місця, де ви називаєте strpos? Або ви хочете змінити лише вміст у межах функції? - Cosmin


Хоча більшість із цих відповідей скажуть вам, якщо в рядку з'являється підрядка, зазвичай це не те, що ви хочете, якщо ви шукаєте конкретну слово, а не а підрядка.

Яка різниця? Підрядки можуть з'являтися в інших словах:

  • "Є" на початку "області"
  • "Є" в кінці "зайця"
  • "Є" в середині "тарифи"

Один із способів пом'якшення цього полягає в тому, щоб використовувати регулярне вираження в поєднанні з кордони слова (\b):

function containsWord($str, $word)
{
    return !!preg_match('#\\b' . preg_quote($word, '#') . '\\b#i', $str);
}

Цей метод не має тих самих помилкових спрацьовувань, які було зазначено вище, але у нього є окремі крайові випадки. Межі слів зібрані за символами без слів (\W), яким буде все, що не є a-z, A-Z, 0-9, або _. Це означає, що цифри та підкреслення будуть зараховуватися як символи слів, і такі сценарії не будуть виконані:

  • "Є" в "Що ви думаєте?"
  • "Є" в "lol u dunno wut those4?"

Якщо ви хочете щось більш точного, ніж це, вам слід почати аналіз синтаксису англійської мови, і це досить велика банка черв'яків (і припускає належне використання синтаксису в будь-якому випадку, що не завжди дається).


113



це повинно бути канонічною відповіддю. Тому що ми шукаємо слова і ні підрядки, відповідний регулярний вираз. Я також додати це \b відповідає двом речам, що \W ні, що робить його чудовою для знахідки слова в рядку: він співпадає з початком рядка (^) і кінець рядка ($) - code_monk
Це не працює: 3v4l.org/vPk2V - Jimbo
це повинна бути правильною відповіддю .. решту відповідей знайдете "є" у рядку, як "ви дбаєте" .. Як згадував @Dtest - Robert Sinclair
@ Роберт Сінкллер Це так погано? Якщо ви запитаєте мене, чи містить рядок "ви доглядає" слова "є", я б сказав "так". Слово "є" явно є підрядкою цього рядка. Це окремий запит від "" "Є" є "одним з слів у рядку" Ви турбуєтеся "" "". - Paulpro
@Paulpro Eventhough OP не вказав, що $ a - це фраза, я впевнений, що це мається на увазі. Отже, його питання полягало в тому, як виявляти Слово всередині фрази. Не в тому випадку, якщо в слові є Слово всередині нього, я б припустив, було б нерелевантним частіше, ніж ні. - Robert Sinclair


Щоб визначити, чи містить рядок інший рядок, ви можете використовувати функцію PHP strpos ().

int strpos ( string $haystack , mixed $needle [, int $offset = 0 ] )

<?php

$haystack = 'how are you';
$needle = 'are';

if (strpos($haystack,$needle) !== false) {
    echo "$haystack contains $needle";
}

?>

ОБЕРЕЖНО:

Якщо голка, яку ви шукаєте, знаходиться на початку стінки сіна, вона поверне позицію 0, якщо ви зробите це == порівняти це не буде працювати, вам потрібно буде зробити a ===

А. == знак - це порівняння та тестування, чи має значення змінної / вираження / константа ліворуч значення, яке має значення для змінної / вираження / константи праворуч.

А. === знак є порівнянням, щоб побачити, чи є дві змінні / вирази / константи рівні ANDмають один і той же тип, тобто обидва є рядками або обидва цілі числа.


93



цитувати джерело? maxi-pedia.com/string+contains+substring+PHP - btk


Використовуючи strstr() або stristr() якщо ваш пошуковий запит має бути бездокументарним, це ще один варіант.


57



Примітка на php.net/manual/en/function.strstr.php сторінка: Примітка. Якщо ви хочете лише визначити, чи є конкретна голка в стійці сіна, використовуйте швидше і менш інтенсивну функцію strpos (). - Jo Smo
@ tastro Чи є якісь репутаційні тести на цьому? - Wayne Whitty
Це може бути повільніше, але IMHO strstr($a, 'are') набагато елегантніше, ніж потворний strpos($a, 'are') !== false. PHP дійсно потребує a str_contains() функція - Paul Spiegel


Подивись на strpos():

<?php
    $mystring = 'abc';
    $findme   = 'a';
    $pos = strpos($mystring, $findme);

    // Note our use of ===. Simply, == would not work as expected
    // because the position of 'a' was the 0th (first) character.
    if ($pos === false) {
        echo "The string '$findme' was not found in the string '$mystring'.";
    }
    else {
        echo "The string '$findme' was found in the string '$mystring',";
        echo " and exists at position $pos.";
    }
?>

55