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


2661

Xem xét:

$a = 'How are you?';

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

Giả sử tôi có đoạn mã trên, cách viết câu lệnh if ($a contains 'are')đúng là gì?

Câu trả lời:


6893

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

$a = 'How are you?';

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

Lưu ý rằng việc sử dụng !== falselà cố ý (không phải != falsevà cũng không === truesẽ trả lại kết quả mong muốn); strpos()trả về giá trị bù mà chuỗi kim bắt đầu trong chuỗi haystack hoặc boolean falsenếu không tìm thấy kim. Vì 0 là phần bù 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').


261
Rất muộn đến 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

167
@DTest - vâng tất nhiên nó sẽ trả về đúng vì chuỗi chứa 'are'. Nếu bạn đang tìm kiếm cụ thể cho từ IS thì bạn sẽ cần thực hiện thêm các kiểm tra như, ví dụ, kiểm tra xem có ký tự hoặc khoảng
trắng

40
Ý kiến ​​rất tốt ở trên! Tôi không bao giờ sử dụng! = Hoặc ==, sau tất cả! == và === là tùy 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, v.v.).
Melsi

10
@jsherk Tại sao không regexes, sau đó? Một cái gì đó như "là".
Giulio Muscarello

22
Tôi có xu hướng tránh vấn đề này bằng cách luôn luôn sử dụng strpos($a, 'are') > -1để kiểm tra sự thật. Từ góc độ gỡ lỗi, tôi thấy bộ não của mình lãng phí ít chu kỳ đồng hồ hơn để xác định xem dòng có được viết chính xác hay không khi tôi không phải đếm các dấu bằng nhau liền kề.
Equazcion

608

Bạn có thể sử dụng các biểu thức thông thường, sẽ tốt hơn khi kết hợp từ so với strposnhư được đề cập bởi những người dùng khác, nó cũng sẽ trả về đúng cho các chuỗi như giá vé, chăm sóc, nhìn chằm chằm, v.v. Điều này có thể tránh được trong cách diễn đạt thông thường bằng cách sử dụng ranh giới từ.

Một kết hợp đơ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, strposnhanh hơn khoảng ba lần và trong tâm trí, khi tôi thực hiện một triệu so sánh cùng một lúc, phải mất preg_match1,5 giây để hoàn thành và strposmất 0,5 giây.

Chỉnh sửa: Để tìm kiếm bất kỳ phần nào của chuỗi, không chỉ từng chữ, tôi khuyên bạn nên sử dụng một biểu thức thông thường như

$a = 'How are you?';
$search = 'are y';
if(preg_match("/{$search}/i", $a)) {
    echo 'true';
}

Phần icuối của biểu thức chính quy thay đổi biểu thức chính quy thành không phân biệt chữ hoa chữ thường, nếu bạn không muốn điều đó, bạn có thể bỏ nó.

Bây giờ, điều này có thể khá rắc rối trong một số trường hợp vì chuỗi tìm kiếm $ không được vệ sinh theo bất kỳ cách nào, ý tôi là, nó có thể không vượt qua kiểm tra trong một số trường hợp như $searchlà đầu vào của người dùng, họ có thể thêm một số chuỗi có thể hoạt động như một số biểu hiện chính quy khác nhau ...

Ngoài ra, đây là một công cụ tuyệt vời để kiểm tra và xem giải thích về các biểu thức chính quy khác nhau Regex101

Để kết hợp cả hai bộ chức năng thành một chức năng đa mục đích duy nhất (bao gồm cả độ nhạy trường hợp có thể lựa chọn), bạn có thể sử dụng một cái gì đó như thế này:

function FindString($needle,$haystack,$i,$word)
{   // $i should be "" or "i" for case insensitive
    if (strtoupper($word)=="W")
    {   // if $word is "W" then word search instead of string in string search.
        if (preg_match("/\b{$needle}\b/{$i}", $haystack)) 
        {
            return true;
        }
    }
    else
    {
        if(preg_match("/{$needle}/{$i}", $haystack)) 
        {
            return true;
        }
    }
    return false;
    // Put quotes around true and false above to return them as strings instead of as bools/ints.
}

9
@ Alexander.Plutov thứ hai trong số tất cả các bạn đang cho tôi -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/ Từ
Breezer

64
+1 Đây 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 mọi cách để tìm kiếm bất kỳ chuỗi con nào của riêng họ và thật hữu ích khi đề xuất này đượ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 mình.
Samoody

72
Về mặt kỹ thuật, câu hỏi hỏi làm thế nào để tìm các từ không phải là một 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 lựa chọn thay thế luôn hữu ích.

15
+1 cho câu trả lời và -1 cho nhận xét @ plutov.by bởi vì, strpose chỉ là một kiểm tra duy nhất trong khi regrec bạn có thể kiểm tra nhiều từ cùng một lúc ex: preg_match (/ are | you | not /)
albanx

4
Biểu thức chính quy nên là phương pháp cuối cùng. Việc sử dụng chúng trong các nhiệm vụ tầm thường nên được khuyến khích. Tôi nhấn mạnh vào điều này từ độ cao của nhiều năm đào mã xấu.
yentsun

257

Đây là một chức năng 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;
}

74
@RobinvanBaalen Trên thực tế, nó có thể cải thiện khả năng đọc mã. Ngoài ra, downvote được cho là cho (rất) câu trả lời xấu, không phải cho câu trả lời "trung lập".
Xaqq

37
Các chức năng @RobinvanBaalen gần như theo định nghĩa về tính dễ đọc (để truyền đạt ý tưởng về những gì bạn đang làm). So sánh cái nào dễ đọc hơn: if ($email->contains("@") && $email->endsWith(".com)) { ...hoặcif (strpos($email, "@") !== false && substr($email, -strlen(".com")) == ".com") { ...
Brandin

3
@RobinvanBaalen trong các quy tắc cuối có nghĩa là bị phá vỡ. Nếu không, mọi người sẽ không nghĩ ra những cách làm sáng tạo mới hơn :). Thêm vào đó phải thừa nhận tôi gặp khó khăn trong việc bao bọc tâm trí xung quanh những thứ như trên martinfowler.com. Đoán đúng việc cần làm là tự mình thử mọi thứ và tìm ra cách tiếp cận nào thuận tiện nhất.
James P.

5
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ó còn kêu gọi những người tối ưu hóa tốt 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 ​​có điểm hợp lệ. ;)
Tino

18
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ì 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 strpose không? Hay bạn muốn thay đổi chỉ chứa trong hàm ??
Cosmin

143

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

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

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

Một cách để giảm thiểu điều này là sử dụng biểu thức chính quy 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 dương tính giả được ghi nhận ở trên, nhưng nó có một số trường hợp cạnh của chính nó. Lời ranh giới phù hợp trên các ký tự không-word ( \W), mà sẽ được bất cứ điều gì đó không phải là a-z, A-Z, 0-9, hoặc _. Điều đó có nghĩa là các chữ số và dấu gạch dưới sẽ được tính là các ký tự từ và các tình huống như thế này sẽ thất bại:

  • "Là" trong "Bạn đang nghĩ gì?"
  • "Là" trong "lol u dunno wut 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 thực hiện phân tích cú pháp tiếng Anh và đó là một con giun khá lớn (và giả sử sử dụng cú pháp đúng cách, dù sao, không phải lúc nào cũng được đưa ra).


24
đây phải là câu trả lời kinh điển Bởi vì chúng tôi đang tìm kiếm các từ và không phải là chuỗi con , regex là phù hợp. Tôi cũng sẽ thêm vào đó \bkhớp với hai thứ \Wkhông phù hợp , điều này thật tuyệt vời khi tìm từ trong chuỗi: Nó khớp với đầu chuỗi ( ^) và cuối chuỗi ( $)
code_monk

đây phải là câu trả lời đúng .. phần còn lại của câu trả lời sẽ tìm "là" trong một chuỗi như "bạn có quan tâm" .. Như đã đề cập bởi @Dtest
Robert Sinclair

@RobertSinclair Điều đó có tệ lắm không? Nếu bạn hỏi tôi rằng chuỗi "do you care" có chứa từ "là" tôi sẽ nói "có". Từ "are" 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ừ "" "Is" là "một trong những từ trong chuỗi" bạn có quan tâm "" "" không.
Paul

@Paulpro Sự kiện OP không chỉ định $ a là cụm từ, tôi khá chắc chắn rằng nó được ngụ ý. Vì vậy, câu hỏi của anh là làm thế nào để phát hiện Lời bên trong Cụm từ. Không phải nếu một từ có chứa một từ bên trong nó, mà tôi cho rằng sẽ không liên quan thường xuyên hơn là không.
Robert Sinclair

@Jimbo nó hoạt động, bạn chỉ thiếu `\` 3v4l.org/ZRpYi
Metalweirdo

125

Để xác định xem một chuỗi có chứa một chuỗi khác hay không, bạn có thể sử dụng hàm PHP strpose () .

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 ở đầu đống cỏ khô, nó sẽ trả về vị trí 0, nếu bạn thực hiện một phép ==so sánh sẽ không hoạt động, bạn sẽ cần phải làm một===

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

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


67

Nhìn vàostrpos() :

<?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.";
    }
?>

62

Sử dụng strstr()hoặc 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 lựa chọn khác.


9
Một ghi chú trên trang php.net/manual/en/feft.strstr.php : 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 strpose () nhanh hơn và ít bộ nhớ hơn.
Jo Smo

@tastro Có điểm chuẩn nào uy tín 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')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

Nó làm tôi suy nghĩ rằng đây không phải là câu trả lời được chấp nhận
Kurdtpage

45

Sử dụng kết hợp không phân biệt chữ hoa chữ thường bằng cách sử dụng stripos():

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

45

Nhận xét ngang hàng với Samoody và Lego Stormtroopr.

Nếu bạn đang tìm kiếm một thuật toán PHP để xếp hạng kết quả tìm kiếm dựa trên mức độ gần gũi / mức độ liên quan của nhiều từ thì đây là cách nhanh chóng và dễ dàng để tạo kết quả tìm kiếm chỉ với PHP:

Các vấn đề với các phương pháp boolean tìm kiếm khác như strpos(), preg_match(), strstr()hoặcstristr()

  1. không thể tìm kiếm nhiều từ
  2. kết quả là không được xếp hạng

Phương pháp PHP dựa trên Mô hình không gian vectơtf-idf (thuật ngữ tần số tài liệu nghịch đảo tần số):

Nghe có vẻ khó khăn nhưng dễ dàng đáng ngạc nhiên.

Nếu chúng ta muốn tìm kiếm nhiều từ trong một chuỗi, vấn đề cốt lõi là làm thế nào chúng ta gán trọng số cho từng từ đó?

Nếu chúng ta có thể cân nhắc các thuật ngữ trong một chuỗi dựa trên mức độ đại diện của toàn bộ chuỗi, chúng ta có thể sắp xếp các kết quả của mình theo các chuỗi phù hợp nhất với truy vấn.

Đây là ý tưởng của mô hình không gian vectơ, không xa cách hoạt động của tìm kiếm toàn văn bản SQL:

function get_corpus_index($corpus = array(), $separator=' ') {

    $dictionary = array();

    $doc_count = array();

    foreach($corpus as $doc_id => $doc) {

        $terms = explode($separator, $doc);

        $doc_count[$doc_id] = count($terms);

        // tf–idf, short for term frequency–inverse document frequency, 
        // according to wikipedia is a numerical statistic that is intended to reflect 
        // how important a word is to a document in a corpus

        foreach($terms as $term) {

            if(!isset($dictionary[$term])) {

                $dictionary[$term] = array('document_frequency' => 0, 'postings' => array());
            }
            if(!isset($dictionary[$term]['postings'][$doc_id])) {

                $dictionary[$term]['document_frequency']++;

                $dictionary[$term]['postings'][$doc_id] = array('term_frequency' => 0);
            }

            $dictionary[$term]['postings'][$doc_id]['term_frequency']++;
        }

        //from http://phpir.com/simple-search-the-vector-space-model/

    }

    return array('doc_count' => $doc_count, 'dictionary' => $dictionary);
}

function get_similar_documents($query='', $corpus=array(), $separator=' '){

    $similar_documents=array();

    if($query!=''&&!empty($corpus)){

        $words=explode($separator,$query);

        $corpus=get_corpus_index($corpus, $separator);

        $doc_count=count($corpus['doc_count']);

        foreach($words as $word) {

            if(isset($corpus['dictionary'][$word])){

                $entry = $corpus['dictionary'][$word];


                foreach($entry['postings'] as $doc_id => $posting) {

                    //get term frequency–inverse document frequency
                    $score=$posting['term_frequency'] * log($doc_count + 1 / $entry['document_frequency'] + 1, 2);

                    if(isset($similar_documents[$doc_id])){

                        $similar_documents[$doc_id]+=$score;

                    }
                    else{

                        $similar_documents[$doc_id]=$score;

                    }
                }
            }
        }

        // length normalise
        foreach($similar_documents as $doc_id => $score) {

            $similar_documents[$doc_id] = $score/$corpus['doc_count'][$doc_id];

        }

        // sort from  high to low

        arsort($similar_documents);

    }   

    return $similar_documents;
}

TRƯỜNG HỢP 1

$query = 'are';

$corpus = array(
    1 => 'How are you?',
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

KẾT QUẢ

Array
(
    [1] => 0.52832083357372
)

TRƯỜNG HỢP 2

$query = 'are';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

CÁC KẾT QUẢ

Array
(
    [1] => 0.54248125036058
    [3] => 0.21699250014423
)

TRƯỜNG HỢP 3

$query = 'we are done';

$corpus = array(
    1 => 'how are you today?',
    2 => 'how do you do',
    3 => 'here you are! how are you? Are we done yet?'
);

$match_results=get_similar_documents($query,$corpus);
echo '<pre>';
    print_r($match_results);
echo '</pre>';

CÁC KẾT QUẢ

Array
(
    [3] => 0.6813781191217
    [1] => 0.54248125036058
)

Có rất nhiều cải tiến được thực hiện nhưng các mô hình cung cấp một cách để nhận được kết quả tốt từ các truy vấn tự nhiên, mà không có các toán tử logic như strpos(), preg_match(), strstr()hoặc stristr().

LỢI ÍCH

Tùy chọn loại bỏ sự dư thừa trước khi tìm kiếm các từ

  • do đó giảm kích thước chỉ mục và dẫn đến yêu cầu lưu trữ ít hơn

  • ít đĩa I / O

  • lập chỉ mục nhanh hơn và do đó tìm kiếm nhanh hơn.

1. Bình thường hóa

  • Chuyển đổi tất cả văn bản sang chữ thường

2. Loại bỏ mật khẩu

  • Loại bỏ các từ khỏi văn bản không có nghĩa thực sự (như 'và', 'hoặc', 'the', 'cho', v.v.)

3. Thay thế từ điển

  • Thay thế các từ bằng những từ khác có nghĩa giống hệt hoặc tương tự. (ví dụ: thay thế các trường hợp 'đói' và 'đói' bằng 'đói')

  • Các biện pháp thuật toán tiếp theo (snowball) có thể được thực hiện để tiếp tục giảm các từ theo nghĩa thiết yếu của chúng.

  • Việc thay thế tên màu bằng các số thập lục phân của chúng

  • Việc giảm các giá trị số bằng cách giảm độ chính xác là những cách khác để chuẩn hóa văn bản.

TÀI NGUYÊN


40

Nếu bạn muốn tránh vấn đề "chim ưng" và "sự thật", bạn có thể sử dụng lớp nền:

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

Nó chậm hơn một chút so với strpose nhưng nó tránh được các vấn đề so sánh.


Nó trả về falsecho "bạn có chắc không?" kể từ vị trí cho strpos0
Hafenkranich

30

Một tùy chọn khác là sử dụng hàm strstr () . Cái gì đó như:

if (strlen(strstr($haystack,$needle))>0) {
// Needle Found
}

Điểm cần lưu ý: Hàm strstr () phân biệt chữ hoa chữ thường. Đối với tìm kiếm không phân biệt chữ hoa chữ thường, hãy sử dụng hàm stristr () .


1
strstr () trả về SAI nếu không tìm thấy kim. Vì vậy, một strlen là không cần thiết.
Ayesh K

29
if (preg_match('/(are)/', $a)) {
   echo 'true';
}

3
Tôi nhận được cảnh báo sau:WARNING preg_match(): Delimiter must not be alphanumeric or backslash
Pathros

27

Tôi là một chút ấn tượng rằng không ai trong số các câu trả lời ở đây là sử dụng strpos, strstrvà các chức năng tương tự như đề cập chức năng nhiều byte Chuỗi chưa (2015/05/08).

Về cơ bản, nếu bạn gặp khó khăn trong việc tìm từ có ký tự cụ thể cho một số ngôn ngữ , chẳng hạn như tiếng Đức, tiếng Pháp, tiếng Bồ Đào Nha, tiếng Tây Ban Nha, v.v. (ví dụ: ä , é , ô , ç , º , ñ ), bạn có thể muốn đi trước Các chức năng với mb_. Do đó, câu trả lời được chấp nhận sẽ sử dụng mb_strposhoặc mb_stripos(đối với kết hợp không phân biệt chữ hoa chữ thường):

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

Nếu bạn không thể đảm bảo rằng tất cả dữ liệu của bạn là 100% trong UTF-8 , bạn có thể muốn sử dụng các mb_chức năng.

Một bài báo tốt để hiểu tại sao Các nhà phát triển phần mềm Absolute tối thiểu Mỗi Tuyệt đối, tích cực Phải Biết Về Unicode và tự Sets (Không Lý Do!) Bởi Joel Spolsky .


25

Trong PHP, cách tốt nhất để xác minh xem một chuỗi có chứa một chuỗi con nhất định hay không, là sử dụng hàm trợ giúp đơn giản như thế này:

function contains($haystack, $needle, $caseSensitive = false) {
    return $caseSensitive ?
            (strpos($haystack, $needle) === FALSE ? FALSE : TRUE):
            (stripos($haystack, $needle) === FALSE ? FALSE : TRUE);
}

Giải trình:

  • strpos tìm vị trí xuất hiện đầu tiên của chuỗi con phân biệt chữ hoa chữ thường trong chuỗi.
  • stripos tìm vị trí xuất hiện đầu tiên của chuỗi con không phân biệt chữ hoa chữ thường trong chuỗi.
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUEđảm bảo myFunctionluôn trả về giá trị boolean và sửa hành vi không mong muốn khi chỉ số của chuỗi con là 0.
  • $caseSensitive ? A : Bchọn một trong hai strposhoặc striposđể thực hiện công việc, tùy thuộc vào giá trị của $caseSensitive.

Đầu ra:

var_dump(contains('bare','are'));            // Outputs: bool(true)
var_dump(contains('stare', 'are'));          // Outputs: bool(true)
var_dump(contains('stare', 'Are'));          // Outputs: bool(true)
var_dump(contains('stare', 'Are', true));    // Outputs: bool(false)
var_dump(contains('hair', 'are'));           // Outputs: bool(false)
var_dump(contains('aren\'t', 'are'));        // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are'));        // Outputs: bool(true)
var_dump(contains('Aren\'t', 'are', true));  // Outputs: bool(false)
var_dump(contains('aren\'t', 'Are'));        // Outputs: bool(true)
var_dump(contains('aren\'t', 'Are', true));  // Outputs: bool(false)
var_dump(contains('broad', 'are'));          // Outputs: bool(false)
var_dump(contains('border', 'are'));         // Outputs: bool(false)

22

Chức năng dưới đây cũng hoạt động và không phụ thuộc vào bất kỳ chức năng nào khác; nó chỉ sử dụng thao tác chuỗi PHP gốc. Cá nhân, tôi không khuyên bạn điều này, nhưng bạn có thể thấy nó hoạt động như thế nào:

<?php

if (!function_exists('is_str_contain')) {
  function is_str_contain($string, $keyword)
  {
    if (empty($string) || empty($keyword)) return false;
    $keyword_first_char = $keyword[0];
    $keyword_length = strlen($keyword);
    $string_length = strlen($string);

    // case 1
    if ($string_length < $keyword_length) return false;

    // case 2
    if ($string_length == $keyword_length) {
      if ($string == $keyword) return true;
      else return false;
    }

    // case 3
    if ($keyword_length == 1) {
      for ($i = 0; $i < $string_length; $i++) {

        // Check if keyword's first char == string's first char
        if ($keyword_first_char == $string[$i]) {
          return true;
        }
      }
    }

    // case 4
    if ($keyword_length > 1) {
      for ($i = 0; $i < $string_length; $i++) {
        /*
        the remaining part of the string is equal or greater than the keyword
        */
        if (($string_length + 1 - $i) >= $keyword_length) {

          // Check if keyword's first char == string's first char
          if ($keyword_first_char == $string[$i]) {
            $match = 1;
            for ($j = 1; $j < $keyword_length; $j++) {
              if (($i + $j < $string_length) && $keyword[$j] == $string[$i + $j]) {
                $match++;
              }
              else {
                return false;
              }
            }

            if ($match == $keyword_length) {
              return true;
            }

            // end if first match found
          }

          // end if remaining part
        }
        else {
          return false;
        }

        // end for loop
      }

      // end case4
    }

    return false;
  }
}

Kiểm tra:

var_dump(is_str_contain("test", "t")); //true
var_dump(is_str_contain("test", "")); //false
var_dump(is_str_contain("test", "test")); //true
var_dump(is_str_contain("test", "testa")); //flase
var_dump(is_str_contain("a----z", "a")); //true
var_dump(is_str_contain("a----z", "z")); //true 
var_dump(is_str_contain("mystringss", "strings")); //true 

13
Bạn có thể vui lòng cho tôi biết tại sao trên thế giới bạn sẽ sử dụng một chức năng như thế này không, khi strpose là một giải pháp hoàn toàn khả thi? ...
sg3s

3
@ sg3s: bạn hoàn toàn đúng, tuy nhiên, strpose cũng dựa trên một cái gì đó tương tự, tôi cũng không đăng nó cho đại diện chỉ để chia sẻ một chút kiến ​​thức
Jason OOO

var_dump cuối cùng là sai
Nắng

1
@Sunny: đó là lỗi đánh máy: var_dump (is_str_contain ("mystringss", "chuỗi")); // đúng
Jason OOO

22

Bạn có thể sử dụng strstrchức năng:

$haystack = "I know programming";
$needle   = "know";
$flag = strstr($haystack, $needle);

if ($flag){

    echo "true";
}

Không sử dụng chức năng sẵn có:

$haystack  = "hello world";
$needle = "llo";

$i = $j = 0;

while (isset($needle[$i])) {
    while (isset($haystack[$j]) && ($needle[$i] != $haystack[$j])) {
        $j++;
        $i = 0;
    }
    if (!isset($haystack[$j])) {
        break;
    }
    $i++;
    $j++;

}
if (!isset($needle[$i])) {
    echo "YES";
}
else{
    echo "NO ";
}

2
Tai nạn nếu bạn tìm kiếm từ đầu tiên.
T30

20

Tôi đã có một số rắc rối với điều này, và cuối cùng tôi đã chọn để tạo ra giải pháp của riêng tôi. Không sử dụng công cụ biểu thức chính quy :

function contains($text, $word)
{
    $found = false;
    $spaceArray = explode(' ', $text);

    $nonBreakingSpaceArray = explode(chr(160), $text);

    if (in_array($word, $spaceArray) ||
        in_array($word, $nonBreakingSpaceArray)
       ) {

        $found = true;
    }
    return $found;
 }

Bạn có thể nhận thấy rằng các giải pháp trước đây không phải là câu trả lời cho từ đang được sử dụng làm tiền tố cho từ khác. Để sử dụng ví dụ của bạn:

$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";

Với các mẫu ở trên, cả $a$bchứa $c, nhưng bạn có thể muốn hàm của bạn cho bạn biết rằng chỉ $achứa $c.


1
bạn có thể có nghĩa là: $found = falselúc bắt đầu
chậm

1
chức năng của bạn có thể không hoạt động nếu từ được liên kết với dấu phẩy, dấu hỏi hoặc dấu chấm. ví dụ: "những gì bạn thấy là những gì bạn nhận được." và bạn muốn xác định xem "get" có trong câu không. Lưu ý dừng hoàn toàn bên cạnh "nhận". Trong trường hợp này, hàm của bạn trả về false. nên sử dụng biểu thức chính quy hoặc giá trị cơ bản (tôi nghĩ dù sao nó cũng sử dụng biểu thức chính quy) để tìm kiếm / thay thế chuỗi.
lightbringer

@lightbringer bạn không thể sai hơn với đề xuất của bạn, điều đó có nghĩa gì với bạn "nó được đề xuất"? không có người tối cao nào đề nghị hay tán tỉnh. Đó là về việc sử dụng công cụ biểu thức chính quy trong php là một lỗ đen trong chính ngôn ngữ, bạn có thể muốn thử đặt một kết hợp biểu thức chính quy trong một vòng lặp và đánh giá kết quả.
Decebal

Câu trả lời này được thể hiện kém và thất bại với nhiều kịch bản mở rộng. Tôi không thấy bất kỳ lợi ích trong việc giải trí kỹ thuật này. Đây là chức năng tùy chỉnh tinh chỉnh và cuộc gọi lặp: 3v4l.org/E9dfD Tôi không quan tâm đến việc chỉnh sửa wiki này vì tôi thấy nó lãng phí thời gian của các nhà nghiên cứu.
mickmackusa

18

Một tùy chọn khác để tìm sự xuất hiện của một từ trong chuỗi bằng strstr ()stristr () giống như sau:

<?php
    $a = 'How are you?';
    if (strstr($a,'are'))  // Case sensitive
        echo 'true';
    if (stristr($a,'are'))  // Case insensitive
        echo 'true';
?>

Điều này là ngược. Các itrong stristrtượng trưng cho không nhạy cảm.
Adam Merrifield

18

Rất nhiều câu trả lời sử dụng substr_countkiểm tra nếu kết quả là >0. Nhưng vì ifcâu lệnh coi zero giống như false , bạn có thể tránh kiểm tra đó và viết trực tiếp:

if (substr_count($a, 'are')) {

Để kiểm tra nếu không có, thêm !toán tử:

if (!substr_count($a, 'are')) {

Chà ... đúng một phần, trong php 0 == false là đúng, nhưng 0 === sai là sai
Andrejs Gubars

17

Nó có thể được thực hiện theo ba cách khác nhau:

 $a = 'How are you?';

1- stristr ()

 if (strlen(stristr($a,"are"))>0) {
    echo "true"; // are Found
 } 

2- strpose ()

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

3- preg_match ()

 if( preg_match("are",$a) === 1) {
   echo "true"; // are Found
 }

tốt, nhưng preg_match rất rủi ro vì nó có thể trả về false hoặc 0. Bạn nên kiểm tra === 1 trong # 3
Shapeshifter

14

Phiên bản tay ngắn

$result = false!==strpos($a, 'are');

5
Mặc dù đoạn mã này có thể giải quyết câu hỏi, bao gồm một lời giải thích thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn đang trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn.
Bono

14

Để tìm một "từ", thay vì sự xuất hiện của một loạt các chữ cái trong thực tế có thể là một phần của một từ khác, sau đây sẽ là một giải pháp tốt.

$string = 'How are you?';
$array = explode(" ", $string);

if (in_array('are', $array) ) {
    echo 'Found the word';
}

5
nó sẽ thất bại nếu $stringAre are, are?
Nắng

13

Bạn nên sử dụng định dạng Không phân biệt chữ hoa chữ thường, vì vậy nếu giá trị được nhập nằm trong smallhoặc capsnó không quan trọng.

<?php
$grass = "This is pratik joshi";
$needle = "pratik";
if (stripos($grass,$needle) !== false) { 

 /*If i EXCLUDE : !== false then if string is found at 0th location, 
   still it will say STRING NOT FOUND as it will return '0' and it      
   will goto else and will say NOT Found though it is found at 0th location.*/
    echo 'Contains word';
}else{
    echo "does NOT contain word";
}
?>

Ở đây, các sọc tìm thấy kim trong heystack mà không cần xem xét trường hợp (nhỏ / mũ).

Mẫu PHPCode có đầu ra


13

Có lẽ bạn có thể sử dụng một cái gì đó như thế này:

<?php
    findWord('Test all OK');

    function findWord($text) {
        if (strstr($text, 'ok')) {
            echo 'Found a word';
        }
        else
        {
            echo 'Did not find a word';
        }
    }
?>

12

Không sử dụng preg_match()nếu bạn chỉ muốn kiểm tra nếu một chuỗi được chứa trong một chuỗi khác. Sử dụng strpos()hoặc strstr()thay vào đó vì chúng sẽ nhanh hơn. ( http://in2.php.net/preg_match )

if (strpos($text, 'string_name') !== false){
   echo 'get the string';
}

12

Nếu bạn muốn kiểm tra xem chuỗi có chứa một số từ cụ thể không, bạn có thể thực hiện:

$badWords = array("dette", "capitale", "rembourser", "ivoire", "mandat");

$string = "a string with the word ivoire";

$matchFound = preg_match_all("/\b(" . implode($badWords,"|") . ")\b/i", $string, $matches);

if ($matchFound) {
    echo "a bad word has been found";
}
else {
    echo "your string is okay";
}

Điều này rất hữu ích để tránh thư rác khi gửi email chẳng hạn.


10

Hàm strpose hoạt động tốt, nhưng nếu bạn muốn case-insensitivekiểm tra một từ trong đoạn văn thì bạn có thể sử dụng striposchức năng củaPHP .

Ví dụ,

$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
    // Word does not exist
}
else {
    // Word exists
}

Tìm vị trí xuất hiện đầu tiên của chuỗi con không phân biệt chữ hoa chữ thường trong chuỗi.

Nếu từ không tồn tại trong chuỗi thì nó sẽ trả về false nếu không nó sẽ trả về vị trí của từ.


9

Bạn cần sử dụng các toán tử giống hệt / không giống nhau vì strpose có thể trả về 0 làm giá trị chỉ mục. Nếu bạn thích các toán tử ternary, hãy cân nhắc sử dụng các thao tác sau (có vẻ hơi ngược tôi sẽ thừa nhận):

echo FALSE === strpos($a,'are') ? 'false': 'true';

8

Kiểm tra xem chuỗi có chứa từ cụ thể không?

Điều này có nghĩa là chuỗi phải được giải quyết thành các từ (xem ghi chú bên dưới).

Một cách để làm điều này và chỉ định các dấu phân cách là sử dụng preg_split( doc ):

<?php

function contains_word($str, $word) {
  // split string into words
  // separators are substrings of at least one non-word character
  $arr = preg_split('/\W+/', $str, NULL, PREG_SPLIT_NO_EMPTY);

  // now the words can be examined each
  foreach ($arr as $value) {
    if ($value === $word) {
      return true;
    }
  }
  return false;
}

function test($str, $word) {
  if (contains_word($str, $word)) {
    echo "string '" . $str . "' contains word '" . $word . "'\n";
  } else {
    echo "string '" . $str . "' does not contain word '" . $word . "'\n" ;
  }
}

$a = 'How are you?';

test($a, 'are');
test($a, 'ar');
test($a, 'hare');

?>

Chạy cho

$ php -f test.php                   
string 'How are you?' contains word 'are' 
string 'How are you?' does not contain word 'ar'
string 'How are you?' does not contain word 'hare'

Ghi chú: Ở đây chúng tôi không có nghĩa là từ cho mỗi chuỗi ký hiệu.

Một định nghĩa thực tế của từ theo nghĩa là công cụ biểu thức chính quy PCRE, trong đó các từ là các chuỗi con chỉ bao gồm các ký tự từ, được phân tách bằng các ký tự không phải từ.

Ký tự "từ" là bất kỳ chữ cái hoặc chữ số hoặc ký tự gạch dưới, nghĩa là, bất kỳ ký tự nào có thể là một phần của "từ" Perl. Định nghĩa của các chữ cái và chữ số được điều khiển bởi các bảng ký tự của PCRE và có thể thay đổi nếu diễn ra kết hợp cụ thể theo địa phương (..)


7

Một giải pháp khác cho một chuỗi cụ thể:

$subject = 'How are you?';
$pattern = '/are/';
preg_match($pattern, $subject, $match);
if ($match[0] == 'are') {
    echo true;
}

Bạn cũng có thể sử dụng strpos()chức năng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.