한글 - php 특정문자 포함




문자열에 특정 단어가 포함되어 있는지 어떻게 확인합니까? (20)

중히 여기다:

$a = 'How are you?';

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

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


문자열에 특정 단어가 포함되어 있는지 확인하십시오.

이것은 문자열이 단어로 해석되어야 함을 의미합니다 (아래 참고 참조).

이 작업을 수행하고 구분 기호를 지정하는 한 가지 방법은 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');

?>

달려라.

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

참고 : 여기서 우리는 기호의 모든 연속에 대한 단어를 의미하지는 않습니다.

실용적인 단어 정의는 PCRE 정규 표현 엔진입니다. 여기서 단어는 단어 문자로만 구성된 부분 문자열이며 단어가 아닌 문자로 구분됩니다.

"단어"문자는 임의의 문자 또는 숫자 또는 밑줄 문자, 즉 Perl "단어"의 일부가 될 수있는 문자입니다. 문자 및 숫자의 정의는 PCRE의 문자 테이블에 의해 제어되며 로케일 특정 일치가 발생하면 달라질 수 있습니다 (..)


"거짓"및 "진실"문제를 피하려면 substr_count를 사용할 수 있습니다.

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

strpos보다 약간 느리지 만 비교 문제는 피할 수 있습니다.


PHP에서 문자열에 특정 하위 문자열이 포함되어 있는지 확인하는 가장 좋은 방법은 다음과 같은 간단한 도우미 함수를 사용하는 것입니다.

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

설명:

  • strpos() 는 문자열에서 대소 문자가 구분되는 하위 문자열의 첫 번째 발생 위치를 찾습니다.
  • stripos() 는 문자열에서 대 / 소문자를 구분하지 않는 부분 문자열이 처음 나타나는 위치를 찾습니다.
  • myFunction($haystack, $needle) === FALSE ? FALSE : TRUE myFunction($haystack, $needle) === FALSE ? FALSE : TRUE 는 부분 문자열의 인덱스가 0 일 때 myFunction 항상 부울을 반환하고 예기치 않은 동작을 수정하도록합니다.
  • $caseSensitive ? A : B $caseSensitive ? A : B$caseSensitive 의 값에 따라 작업을 수행하기 위해 strpos() 또는 stripos() 를 선택합니다.

산출:

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)

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가 인덱스 값으로 0을 반환 할 수 있기 때문에 동일한 연산자 / 동일하지 않은 연산자를 사용해야합니다. 삼항 연산자가 마음에 들면, 다음을 사용하는 것을 고려해보십시오 (조금 뒤에서 나는 인정할 것입니다) :

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

나는 이것에 약간의 문제가 있었고 마침내 나는 내 자신의 해결책을 창조하기로 결정했다. 정규 표현식 엔진을 사용하지 않고 :

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

이전 솔루션은 다른 단어의 접두사로 사용되는 단어에 대한 대답이 아님을 알 수 있습니다. 예제를 사용하려면 다음을 수행하십시오.

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

위의 예제에서 $a$b 는 모두 $c 포함하지만, $a 에만 $c 포함한다고 말할 수 있습니다.


대 / 소문자를 구분하지 않으면 strstr() 또는 stristr() 하는 것이 다른 옵션입니다.


대소 문자를 구분하지 않는 형식을 사용해야합니다. 입력 된 값이 small 거나 caps 되어도 문제가되지 않습니다.

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

여기서 stripos는 case 고려 하지 않고 heystack에서 바늘을 찾습니다 (small / caps).

출력이있는 PHPCode 샘플


문자열에 다른 문자열이 포함되어 있는지 확인하려면 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 == 부호는 비교이며 왼쪽 변수 / 표현식 / 상수가 오른쪽 / 변수 / 표현식 / 상수와 동일한 값을 갖는지 여부를 테스트합니다.

A === 부호는 두 개의 변수 / 표현식 / 상수가 같고 동일한 유형인지 여부를 확인하기위한 비교입니다. 즉, 둘 다 문자열이거나 둘 다 정수입니다.


문자열에 몇 가지 구체적인 단어가 포함되어 있는지 확인하려면 다음을 수행 할 수 있습니다.

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

예를 들어 이메일을 보낼 때 스팸을 피하는 데 유용합니다.


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

 $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 문자열 조작 만 사용합니다. 개인적으로는 권장하지 않지만 작동 원리는 다음과 같습니다.

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

테스트:

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 

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

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

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

이것을 줄이는 한 가지 방법은 단어 경계 ( \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에 비해 단어 일치가 더 좋습니다. 운임, 치료, 응시 등과 같은 문자열에도 true를 반환합니다. 정규 표현식에서는 단어 경계를 사용하여 피할 수 있습니다.

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

$a = 'How are you?';

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

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


한 문자열이 다른 문자열에 포함되어 있는지 확인하려는 경우 preg_match() 사용하지 마십시오. 더 빨라질수록 strpos() 또는 strstr() 대신 사용 strpos() . ( http://in2.php.net/preg_match )

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

stripos() 사용하여 대소 문자 일치를 사용합니다.

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

strpos() 함수를 사용할 수 있습니다. strpos() 함수는 하나의 문자열이 다른 문자열에 포함되어 있는지를 찾는 데 사용됩니다.

$a = 'How are you?';

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

!== false 의 사용은 고의적입니다. strpos() 는 haystack 문자열에서 바늘 문자열이 시작되는 오프셋을 반환하거나 needle이 발견되지 않으면 false 반환합니다. 0은 유효한 오프셋이고 0은 "거짓"이므로 !strpos($a, 'are') 와 같은 간단한 구문을 사용할 수 없습니다.


substr_count 를 사용하는 많은 답변은 결과가 >0 인지 확인합니다. 그러나 if은 false와 동일한 0을 고려하기 때문에 검사를 피하고 직접 작성할 수 있습니다.

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

존재 하지 않는지 확인하려면 ! 운영자:

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

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 .


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






string-matching