한글 strpos php 문자열에 특정 단어가 포함되어 있는지 어떻게 확인합니까?



15 Answers

정규 표현식을 사용할 수 있습니다. 다른 사용자가 언급 한 것처럼 strpos에 비해 단어 일치가 더 좋습니다. 운임, 치료, 응시 등과 같은 문자열에도 true를 반환합니다. 정규 표현식에서는 단어 경계를 사용하여 피할 수 있습니다.

간단한 일치는 다음과 같이 보일 수 있습니다.

$a = 'How are you?';

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

성능면에서 strpos는 약 3 배 빨라졌고 마음 속에서 한 번에 100 만회를 비교했을 때 1.5 초로 경기가 끝났고 strpos에는 0.5 초가 걸렸습니다.

php strpos 여러개

중히 여기다:

$a = 'How are you?';

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

위 코드를 가지고 있다고 가정 if ($a contains 'are') 문장을 작성하는 올바른 방법은 무엇입니까?




이 답변의 대부분은 문자열에 하위 문자열이 표시되는지 알려주지 만 일반적으로 하위 단어가 아닌 특정 단어를 찾는 경우 원하는 것이 아닙니다.

차이점이 뭐야? 하위 문자열은 다른 단어 안에 나타날 수 있습니다.

  • "지역"의 시작 부분에있는 "있습니다"
  • "토끼"의 끝에있는 "있다"
  • "운임"의 중간에있는 "있습니다"

이것을 줄이는 한 가지 방법은 단어 경계 ( \b )와 결합 된 정규 표현식을 사용하는 것입니다.

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

이 방법은 위에서 언급 한 것과 동일한 오 탐지 (false positives)를 가지고 있지는 않지만, 자체적 인 몇 가지 단점이 있습니다. 단어 경계는 단어가 아닌 문자 ( \W )와 일치하며 az , AZ , 0-9 또는 _ 이 아닌 문자가됩니다. 즉, 숫자와 밑줄은 단어 문자로 계산 될 것이고이 같은 시나리오는 실패합니다.

  • "무엇을 생각하고 있니?"
  • "are in 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() 사용하여 대소 문자 일치를 사용합니다.

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



Peer to SamGoody와 Lego Stormtroopr의 의견.

여러 단어의 근접성 / 관련성기반으로 검색 결과순위 매기기 위한 PHP 알고리즘을 찾고있는 경우 PHP를 사용하여 검색 결과 를 생성하는 빠르고 쉬운 방법이 있습니다.

strpos() , preg_match() , strstr() 또는 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() , strstr() 또는 stristr() 과 같은 부울 연산자가없는 자연스러운 쿼리에서 좋은 결과를 얻는 방법을 제공합니다.

노타 벤

선택적으로 단어를 검색하기 전에 중복을 제거하십시오.

  • 인덱스 크기를 줄이고 스토리지 요구 사항을 줄입니다.

  • 적은 디스크 I / O

  • 인덱싱 속도가 빨라지고 검색 속도가 빨라집니다.

1. 정규화

  • 모든 텍스트를 소문자로 변환

2. 스톱 워드 제거

  • 실제 의미가없는 텍스트에서 단어를 제거하십시오 (예 : 'and', 'or', 'the', 'for'등)

3. 사전 대체

  • 동일하거나 유사한 의미를 가진 단어로 단어를 대체하십시오. (예 : 'hungrily'와 'hungry'의 인스턴스를 'hunger'로 대체)

  • 추가 알고리즘 측정 (눈덩이)을 수행하여 단어를 본질적인 의미로 더 줄일 수 있습니다.

  • 색상 이름을 16 진수로 대체

  • 정밀도를 줄임으로써 숫자 값을 줄이는 것은 텍스트를 정규화하는 다른 방법입니다.

자원




strpos , strstr 및 이와 유사한 함수를 사용한 응답 중 멀티 바이트 문자열 함수 (2015-05-08)가 아직 언급되지 않았다는 사실에 조금 감탄했습니다.

기본적으로 독일어, 프랑스어, 포르투갈어, 스페인어 등 일부 언어의 문자 (예 : ä , é , ô , ç , º , ñ )로 단어를 찾는 데 어려움 이있는 경우 앞에 함수는 mb_ . 따라서 허용 된 대답 대신 mb_strpos 또는 mb_stripos (대소 문자를 구분하지 않는 일치)를 사용합니다.

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

모든 데이터가 UTF-8로 100 % 보장되지 않는다면, mb_ 함수를 사용하는 것이 mb_ .

절대적으로 모든 소프트웨어 개발자가 절대적으로, 절대적으로 유니 코드와 문자 집합에 대해 알아야 한다는 것을 이해할 수있는 좋은 기사입니다 (변명의 여지가 없습니다!) . Joel Spolsky .




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



strstr 함수를 사용할 수 있습니다.

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

if ($flag){

    echo "true";
}

inbuilt 함수를 사용하지 않고 :

$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');



strstr()stristr() 사용하여 문자열에서 단어의 발생을 찾는 또 다른 옵션은 다음과 같습니다.

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



세 가지 방법으로 수행 할 수 있습니다.

 $a = 'How are you?';

1 stristr ()

 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 검사하려면 PHPstripos 함수를 사용할 수 있습니다.

예를 들어,

$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