php url ワイルド - 文字列に特定の単語が含まれているかどうかを確認するにはどうすればよいですか?



15 Answers

正規表現を使うことができます。他のユーザーが述べたようにstrposと比較して単語マッチングに適しています。運賃、ケア、凝視などの文字列に対してもtrueを返します。これは正規表現では単語境界を使用するだけで簡単に回避できます。

単純な一致は次のようになります。

$a = 'How are you?';

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

性能面では、strposは約3倍速く、一度に100万回比較したときには1.5秒で終了し、strposでは0.5秒かかりました。

カード string search

検討してください:

$a = 'How are you?';

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

上記のコードがあるとします。 if ($a contains 'are') 、文を書く正しい方法は何ですか?




これらの答えのほとんどは、文字列に部分文字列が含まれているかどうかを示していますが、 部分文字列ではなく特定の単語を検索する場合は、通常は必要としません。

違いは何ですか? サブストリングは他の単語の中に現れます:

  • 「エリア」の冒頭の「are」は、
  • "hare"の終わりにある "are"
  • 「運賃」の真ん中の「are」は、

これを軽減する1つの方法は、 単語境界\b )に結合された正規表現を使用することです。

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

このメソッドは、上記の同じ誤検出を持っていませんが、独自のいくつかのエッジケースを持っています。 単語の境界は、単語ではない文字( \W )と一致します。これは、 azAZ0-9 、または_ます。 つまり、数字とアンダースコアは単語文字としてカウントされ、このようなシナリオは失敗します。

  • あなたは何を考えているのですか?
  • 「are are dunno wut are are4?」の「are」は?

これよりも正確なものを望むなら、英語の構文解析をやり始めなければならないでしょう。それはかなり大きなワームです(とにかく、必ずしも与え​​られているわけではない構文の適切な使用を前提としています)。




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



stripos()を使用してcase-insensitveマッチングを利用する:

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



SamGoodyとPeer to SamGoodyとLego Stormtrooprのコメント。

複数の単語の近接性/関連性基づいて検索結果ランク付けするPHPアルゴリズムを探している場合は、PHPのみで検索結果を迅速かつ簡単に生成できます。

strpos()preg_match()stristr()またはstristr()などの他のブール検索メソッドの問題は、

  1. 複数の単語を検索することはできません
  2. 結果はランク付けされていません

ベクトル空間モデルtf-idfに基づくPHPメソッド(周波数逆文書頻度):

それは難しいと聞こえますが、驚くほど簡単です。

文字列中の複数の単語を検索する場合、重大な問題は、それぞれに重みを割り当てる方法です。

それらの文字列がどのように代表的なものであるかに基づいて文字列の中で用語を重み付けすることができれば、クエリに最も一致する結果を並べることができます。

これはベクトル空間モデルの考え方であり、 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;
}

ケース1

$query = 'are';

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

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

結果

Array
(
    [1] => 0.52832083357372
)

ケース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>';

結果

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

ケース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>';

結果

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

改善がたくさんありますが、モデルはstrpos()preg_match()strpos()strpos()などのブール演算子を持たない自然なクエリから良い結果を得る方法を提供します。

NOTA BENE

オプションで、単語を検索する前に冗長性を削除する

  • インデックスのサイズが縮小され、ストレージの必要性が少なくなります

  • 少ないディスクI / O

  • インデックス作成が高速化され、結果として検索が高速化されます。

1.正規化

  • すべてのテキストを小文字に変換する

2.ストップワードの削除

  • 実際の意味を持たないテキストから単語を削除する( 'and'、 'or'、 'the'、 'for'など)

3.辞書置換

  • 同一または類似の意味を持つ他の単語と単語を置き換えます。 (例:「飢えている」と「飢えている」のインスタンスを「空腹」に置き換える)

  • 単語を本質的な意味にさらに減らすために、さらなるアルゴリズム測定(スノーボール)を行うことができる。

  • カラー名を16進数で置き換える

  • 精度を低下させることによる数値の減少は、テキストを正規化する他の方法です。

リソース




strposstrposなどの関数を使用したここでの回答は、 マルチバイト文字列関数についてはまだ触れていませんでした(2015-05-08)。

基本的に、ドイツ語、フランス語、ポルトガル語、スペイン語などの一部の言語固有の文字 (例: äéôçºñを持つ単語を見つけるのが難しい場合は、関数はmb_ 。 したがって、受け入れられた答えは、 mb_strposまたはmb_stripos (大文字と小文字を区別しない一致)を使用します。

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

すべてのデータがUTF-8100%であると保証できない場合mb_関数を使用することをおmb_ます。

なぜすべてのソフトウェア開発者が絶対最小限であるのかを理解するための良い記事は、 Joel Spolskyの Unicodeと文字セット(正当な理由はありません!




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



strstr関数を使用することができます:

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

if ($flag){

    echo "true";
}

組み込み関数を使用しない場合:

$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 ";
}



ショートハンド版

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



stristr()stristr()を使用して文字列から単語の出現を見つける別のオプションは、次のようになります。

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



それは3つの異なる方法で行うことができます:

 $a = 'How are you?';

1-ストリスト()

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

2 strpos()

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

3- preg_match()

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



たぶんあなたは次のようなものを使うことができます:

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

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



strposはインデックス値として0を返すことができるので、同一の/同一ではない演算子を使用する必要があります。 三項演算子が好きな人は、次のようにすることをお勧めします(ちょっと前に私が認めます)。

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



strpos関数は正常に機能しますが、段落内の単語をcase-insensitive調べたいcase-insensitiveは、 PHP stripos関数を使用できPHP

例えば、

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

大文字小文字を区別しない部分文字列が文字列に最初に現れた位置を探します。

単語に文字列が存在しない場合はfalseを返し、そうでなければ単語の位置を返します。




文字列は以下の関数でチェックすることができます:

function either_String_existor_not($str, $character) {
    if (strpos($str, $character) !== false) {
        return true;
    }
    return false;
}



Related