Câu hỏi Làm cách nào để kiểm tra xem chuỗi có chứa một từ cụ thể không?


Xem xét:

$a = 'How are you?';

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

Giả sử tôi có mã ở trên, cách viết đúng câu if ($a contains 'are')?


2668


gốc




Các câu trả lời:


Bạn có thể dùng strpos() chức năng được sử dụng để tìm sự xuất hiện của một chuỗi bên trong một chuỗi khác:

$a = 'How are you?';

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

Lưu ý rằng việc sử dụng !== false là cố ý; strpos() trả về giá trị bù trừ mà chuỗi kim bắt đầu trong chuỗi haystack, hoặc boolean false nếu không tìm thấy kim. Vì 0 là giá trị offset hợp lệ và 0 là "falsey", chúng tôi không thể sử dụng các cấu trúc đơn giản hơn như !strpos($a, 'are').


5448



một điều tôi thấy là nếu "là" là từ đầu tiên, thì mã trên sẽ thất bại vì nó trả về "0" có thể được coi là sai! Để tránh điều này cần đọc nếu (strpos ("x". $ A, 'are')! == false) ..... - Darknight
@Darknight: "0" không được coi là "sai" khi bạn sử dụng! ==. Nó chỉ được xem xét nếu bạn sử dụng! =. - Milan Babuškov
Rất muộn cho bữa tiệc, nhưng hãy cẩn thận với điều này. Điều này cũng sẽ trả về true cho chuỗi 'Bạn có quan tâm không?' - DTest
@DTest - cũng có tất nhiên nó sẽ trả về true vì chuỗi chứa 'are'. Nếu bạn đang tìm kiếm cụ thể cho từ ARE thì bạn sẽ cần phải làm nhiều kiểm tra hơn như, ví dụ, kiểm tra nếu có một ký tự hoặc một khoảng trắng trước A và sau E. - jsherk
Rất tốt ý kiến ​​ở trên! Tôi không bao giờ sử dụng! = Hoặc ==, sau khi tất cả! == và === là lựa chọn tốt nhất (theo ý kiến ​​của tôi) tất cả các khía cạnh được xem xét (tốc độ, độ chính xác, vv). - Melsi


Bạn có thể sử dụng các biểu thức chính quy, tốt hơn cho việc so khớp từ so với strpos như được người dùng khác đề cập, nó cũng sẽ trả về true cho các chuỗi như giá vé, chăm sóc, nhìn chằm chằm vv Điều này có thể tránh được trong cụm từ thông dụng.

Một trận đấu đơn giản cho có thể trông giống như thế này:

$a = 'How are you?';

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

Về mặt hiệu suất, strpos nhanh hơn gấp 3 lần và trong đầu, khi tôi thực hiện một triệu lần so sánh cùng một lúc, nó mất khoảng 1,5 giây để kết thúc và cho strpos mất 0,5 giây.


451



cảm ơn cho đề xuất, mã của bạn hoạt động tốt, nhưng tôi thích sử dụng chức năng strpos. - Charles Yeung
@ Alexander.Plutov thứ hai của tất cả các bạn đang cho tôi một -1 và không phải là câu hỏi? cmon phải mất 2 giây để google câu trả lời google.com/… - Breezer
+1 Đó là một cách khủng khiếp để tìm kiếm một chuỗi đơn giản, nhưng nhiều khách truy cập vào SO đang tìm kiếm bất kỳ cách nào để tìm kiếm bất kỳ đoạn mã nào của riêng họ và điều hữu ích là đề xuất đã được đưa ra. Ngay cả OP có thể đã quá đơn giản - hãy cho anh ta biết về các lựa chọn thay thế của anh ta. - SamGoody
Về mặt kỹ thuật, câu hỏi hỏi làm thế nào để tìm từ ngữ không phải là chuỗi con. Điều này thực sự đã giúp tôi khi tôi có thể sử dụng điều này với các ràng buộc từ regex. Các giải pháp thay thế luôn hữu ích.
1 cho câu trả lời và -1 cho nhận xét @ plutov.by bởi vì, strpos chỉ là một kiểm tra trong khi đó regexp bạn có thể kiểm tra nhiều từ trong cùng một thời điểm cũ: preg_match (/ are | you | not /) - albanx


Đây là một chức năng tiện ích nhỏ hữu ích trong các tình huống như thế này

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

198



@RobinvanBaalen Trên thực tế, nó có thể cải thiện khả năng đọc mã. Ngoài ra, downvotes có nghĩa vụ phải cho (rất) câu trả lời xấu, không cho những người "trung lập". - Xaqq
Chức năng @RobinvanBaalen gần như theo định nghĩa cho khả năng đọc (để truyền đạt ý tưởng về những gì bạn đang làm). So sánh dễ đọc hơn: if ($email->contains("@") && $email->endsWith(".com)) { ... hoặc là if (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ... - Brandin
@RobinvanBaalen trong các quy tắc cuối cùng có nghĩa là để được chia. Nếu không, mọi người sẽ không nghĩ ra những cách sáng tạo mới hơn để làm việc :). Thêm vào đó phải thừa nhận tôi gặp rắc rối khi gói tâm trí xung quanh những thứ như trên martinfowler.com. Đoán điều đúng đắn cần làm là tự mình thử mọi thứ và tìm ra phương pháp nào thuận tiện nhất. - James P.
Một ý kiến ​​khác: Có một chức năng tiện ích mà bạn có thể dễ dàng bọc có thể giúp gỡ lỗi. Ngoài ra nó loundens tiếng kêu cho tối ưu tốt mà loại bỏ chi phí như vậy trong các dịch vụ sản xuất. Vì vậy, tất cả các ý kiến ​​đều có điểm hợp lệ. ;) - Tino
Tất nhiên điều này là hữu ích. Bạn nên khuyến khích điều này. Điều gì sẽ xảy ra nếu trong PHP 100 có một cách mới và nhanh hơn để tìm vị trí chuỗi? Bạn có muốn thay đổi tất cả các địa điểm mà bạn gọi là strpos không? Hay bạn muốn thay đổi chỉ chứa trong hàm? - Cosmin


Trong khi hầu hết các câu trả lời này sẽ cho bạn biết nếu chuỗi con xuất hiện trong chuỗi của bạn, thì đó thường không phải là những gì bạn muốn nếu bạn đang tìm kiếm một từvà không phải chuỗi con.

Có gì khác biệt? Substrings có thể xuất hiện trong các từ khác:

  • "Là" ở đầu "khu vực"
  • "Là" ở cuối "thỏ"
  • "Đang" ở giữa "giá vé"

Một cách để giảm thiểu điều này là sử dụng cụm từ thông dụng kết hợp với ranh giới từ (\b):

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

Phương pháp này không có cùng một mặt tích cực sai được ghi chú ở trên, nhưng nó có một số trường hợp cạnh của riêng nó. Ranh giới từ khớp với các ký tự không phải từ (\W), sẽ là bất kỳ thứ gì không a-z, A-Z, 0-9, hoặc là _. Điều đó có nghĩa là chữ số và dấu gạch dưới sẽ được tính là ký tự từ và các trường hợp như thế này sẽ không thành công:

  • Chữ "là" trong "Cái gì bạn nghĩ?"
  • Các "là" trong "lol u dunno wut những are4?"

Nếu bạn muốn bất cứ điều gì chính xác hơn điều này, bạn sẽ phải bắt đầu phân tích cú pháp ngôn ngữ tiếng Anh, và đó là một lượng lớn các sâu (và giả sử sử dụng đúng cú pháp, dù sao, không phải lúc nào cũng được).


113



đây phải là câu trả lời kinh điển. Bởi vì chúng tôi đang tìm kiếm từ ngữ và không chất nền, regex là thích hợp. Tôi cũng sẽ thêm \b phù hợp với hai điều \W không, điều này thật tuyệt vời cho việc tìm kiếm từ ngữ trong một chuỗi: Nó khớp với đầu chuỗi (^) và kết thúc chuỗi ($) - code_monk
Điều này không hoạt động: 3v4l.org/vPk2V - Jimbo
đây sẽ là câu trả lời đúng .. phần còn lại của câu trả lời sẽ tìm thấy "là" trong một chuỗi như "bạn quan tâm" .. Như đã đề cập bởi @Dtest - Robert Sinclair
@RobertSinclair Điều đó thật tệ? Nếu bạn hỏi tôi nếu chuỗi "bạn quan tâm" có chứa từ "là" tôi sẽ nói "có". Từ "là" rõ ràng là một chuỗi con của chuỗi đó. Đó là một câu hỏi riêng biệt từ "" "Là" là "một trong các từ trong chuỗi" bạn có quan tâm "" "" không. - Paulpro
@Paulpro Eventhough OP đã không chỉ định $ a là một cụm từ, tôi khá chắc chắn nó đã được ngụ ý. Vì vậy, câu hỏi của ông là làm thế nào để phát hiện các từ bên trong cụm từ. Không phải nếu một từ có chứa một từ bên trong của nó, mà tôi sẽ giả định sẽ không liên quan thường xuyên hơn không. - Robert Sinclair


Để xác định xem một chuỗi có chứa một chuỗi khác, bạn có thể sử dụng hàm PHP hay không 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";
}

?>

THẬN TRỌNG:

Nếu kim bạn đang tìm kiếm là lúc bắt đầu haystack nó sẽ trả về vị trí 0, nếu bạn làm một == so sánh điều đó sẽ không hiệu quả, bạn sẽ cần phải làm ===

A == ký hiệu là so sánh và kiểm tra xem biến / biểu thức / hằng số ở bên trái có cùng giá trị với biến / biểu thức / hằng số ở bên phải hay không.

A === dấu là một so sánh để xem liệu hai biến / expresions / hằng số có bằng nhau không ANDcó cùng loại - tức là cả hai là chuỗi hoặc cả hai đều là số nguyên.


93



nguồn trích dẫn? maxi-pedia.com/string+contains+substring+PHP - btk


Sử dụng strstr() hoặc là stristr() nếu tìm kiếm của bạn không phân biệt chữ hoa chữ thường sẽ là một tùy chọn khác.


57



Một ghi chú trên php.net/manual/en/function.strstr.php trang: Lưu ý: Nếu bạn chỉ muốn xác định xem một kim cụ thể có xảy ra trong haystack hay không, hãy sử dụng hàm strpos () thay cho bộ nhớ nhanh hơn và ít bộ nhớ hơn. - Jo Smo
@tastro Có bất kỳ điểm chuẩn có uy tín nào về điều này không? - Wayne Whitty
Điều này có thể chậm hơn, nhưng IMHO strstr($a, 'are') là thanh lịch hơn nhiều so với xấu xí strpos($a, 'are') !== false. PHP thực sự cần một str_contains() chức năng. - Paul Spiegel


Nhìn vào 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





Nếu bạn muốn tránh vấn đề "falsey" và "truthy", bạn có thể sử dụng substr_count:

if (substr_count($a, 'are') > 0) {
    echo "at least one 'are' is present!";
}

Đó là một chút chậm hơn strpos nhưng nó tránh được các vấn đề so sánh.


37





Tận dụng -phép khớp không phân biệt chữ hoa chữ thường sử dụng stripos():

if (stripos($string,$stringToSearch) !== false) {
    echo 'true';
}

37