検討してください:
$a = 'How are you?';
if ($a contains 'are')
echo 'true';
上記のコードがあるとします。ステートメントif ($a contains 'are')
を書くための正しい方法は何ですか?
strpos()
という関数を使って、ある文字列が別の文字列の中に現れるのを見つけることができます。
$a = 'How are you?';
if (strpos($a, 'are') !== false) {
echo 'true';
}
!== false
の使用は故意です。 strpos()
は、針の文字列が干し草の山の文字列で始まるオフセット、または針が見つからない場合はブール値のfalse
を返します。 0は有効なオフセットであり、0は "falsey"であるため、!strpos($a, 'are')
のような単純な構成は使用できません。
正規表現を使うこともできますが、他のユーザが述べたようにstrpos
と比較してWordのマッチングには向いています。運賃、世話、凝視などの文字列にもtrueが返されます。
Areに対する単純な一致は、次のようになります。
$a = 'How are you?';
if (preg_match('/\bare\b/', $a)) {
echo 'true';
}
パフォーマンス面では、strpos
は約3倍高速であり、一度に100万回比較すると、 preg_match
1.5秒かかり、strpos
では0.5秒かかりました。
編集:Wordだけでなく、文字列のどの部分も検索するには、次のような正規表現を使用することをお勧めします。
$a = 'How are you?';
$search 'are y';
if(preg_match("/{$search}/i", $a)) {
echo 'true';
}
正規表現の最後にあるi
は、正規表現を大文字と小文字を区別しないように変更します。それを望まない場合は、省略することができます。
さて、$ search文字列はサニタイズされていないので、これはかなり問題になることがあります。$search
がユーザー入力であるかのように、チェックに合格しない場合がありますいくつかの異なる正規表現のように...
また、これはさまざまな正規表現のテストや説明を見るための優れたツールです。 Regex101
両方の機能を1つの多目的機能(大文字と小文字を区別して選択する機能も含む)に組み合わせるには、次のようにします。
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.
}
これは、このような状況で役立つ便利な関数です。
// returns true if $needle is a substring of $haystack
function contains($needle, $haystack)
{
return strpos($haystack, $needle) !== false;
}
これらの答えのほとんどはあなたの文字列の中に部分文字列があるかどうかを教えてくれるでしょうが、部分文字列ではなく特定のWordを探しているのであれば通常は望みません。
違いは何ですか?部分文字列は他の単語の中に現れることがあります。
これを軽減する1つの方法は、 単語の境界 (\b
)と組み合わせた正規表現を使用することです。
function containsWord($str, $Word)
{
return !!preg_match('#\\b' . preg_quote($Word, '#') . '\\b#i', $str);
}
このメソッドには上記の同じ誤検知はありませんが、独自のEdgeケースがいくつかあります。単語境界は、Word以外の文字(\W
)と一致します。これは、a-z
、A-Z
、0-9
、または_
以外のものになります。つまり、数字やアンダースコアはWordの文字としてカウントされ、このようなシナリオは失敗します。
これよりももっと正確なものが欲しいなら、あなたは英語の構文解析を始めなければなりません、そしてそれはワームのかなり大きい缶です(そして、とにかく構文の適切な使用を仮定します。
文字列に別の文字列が含まれているかどうかを判断するには、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を返します。==
比較を実行しても機能しない場合は、===
を実行する必要があります。
==
記号は比較で、左側の変数/式/定数が右側の変数/式/定数と同じ値であるかどうかをテストします。
===
記号は、2つの変数/式/定数が等しいかどうかを比較するためのものです。AND
は同じ型を持ちます。つまり、両方とも文字列、または両方とも整数です。
<?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.";
}
?>
SamGoodyとLego Stormtrooprのコメントを参照してください。
PHPアルゴリズムを探している場合、近接/関連性に基づいて検索結果をランク付けする PHPのみを使用して、検索結果をすばやく簡単に生成する:
strpos()
、preg_match()
、strstr()
、stristr()
などの他のブール検索メソッドの問題
PHPメソッドに基づく ベクトル空間モデル および tf-idf(用語頻度–逆文書頻度):
難しいように聞こえますが、驚くほど簡単です。
文字列内の複数の単語を検索する場合、核となる問題は、各単語にどのように重みを割り当てるかです。
文字列全体の代表性に基づいて、文字列内の用語に重みを付けることができる場合、クエリに最も一致するもので結果を並べ替えることができます。
これは、ベクトル空間モデルの考え方です。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()
などのブール演算子を持たない自然なクエリから良い結果を得る方法を提供します。
NOTA BENE
オプションで、単語を検索する前に冗長性を排除します
これにより、インデックスサイズが小さくなり、ストレージ要件が少なくなります
ディスクI/Oが少ない
インデックス作成の高速化と検索の高速化。
1.正規化
2.ストップワードの削除
3.辞書置換
単語を、同一または類似の意味を持つ他の単語に置き換えます。 (例: 'hungrily'および 'hungry'のインスタンスを 'hunger'に置き換えます)
単語をその本質的な意味にさらに減らすために、さらなるアルゴリズム手段(スノーボール)を実行することができます。
色の名前を16進数で置き換える
精度を下げることによる数値の削減は、テキストを正規化する他の方法です。
リソース
大文字と小文字を区別しないマッチング using stripos()
を使用してください。
if (stripos($string,$stringToSearch) !== false) {
echo 'true';
}
"falsey"と "truthy"の問題を避けたい場合は、substr_countを使用できます。
if (substr_count($a, 'are') > 0) {
echo "at least one 'are' is present!";
}
それはstrposより少し遅いですが、それは比較問題を避けます。
strpos
、strstr
、および類似の関数を使用した、ここでの回答のどれも Multibyte String Functions (2015-05-08)をまだ言及していないことに私は少し感心します。
基本的に、ドイツ語、フランス語、ポルトガル語、スペイン語など、一部の言語に固有の文字を含む単語を検索できない場合(例:ä、é、ô、ç、º、ñ)、関数の前にmb_
を付けることができます。したがって、受け入れられた回答では、代わりに mb_strpos
または mb_stripos
を使用します(大文字と小文字を区別しない場合)。
if (mb_strpos($a,'are') !== false) {
echo 'true';
}
あなたのデータはすべてUTF-8では100%です を保証できない場合は、mb_
関数を使用することをお勧めします。
すべてのソフトウェア開発者にとって絶対的、絶対的に確実に知っておく必要がある絶対的な最小値(言い訳は必要ありません)by Joel Spolsky。
if (preg_match('/(are)/', $a)) {
echo 'true';
}
以下の機能も機能し、他の機能には依存しません。ネイティブの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
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
が常にブール値を返すようにし、部分文字列のインデックスが0の場合の予期しない動作を修正します。$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)
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 ";
}
私はこれでいくつかの問題を抱えていました、そして最後に私は私自身の解決策を作ることを選びました。 正規表現 engineを使わないで
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;
}
あなたは前の解決策が他のものの接頭辞として使われているWordの答えではないことに気づくかもしれません。あなたの例を使用するために:
$a = 'How are you?';
$b = "a skirt that flares from the waist";
$c = "are";
上記のサンプルでは、$a
と$b
の両方に$c
が含まれていますが、$a
のみに$c
が含まれていることを関数に知らせることができます。
実際に別の単語の一部になる可能性がある一連の文字の出現ではなく、「単語」を見つけるには、次の方法が優れた解決策になります。
$string = 'How are you?';
$array = explode(" ", $string);
if (in_array('are', $array) ) {
echo 'Found the Word';
}
それには3つの方法があります。
$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
}
短縮版
$result = false!==strpos($a, 'are');
大文字と小文字を区別しない形式を使用する必要があります。そのため、入力された値が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は大文字小文字を区別してheystack without _に針を見つけます(small/caps)。
substr_count
を使用する回答の多くは、結果が>0
であるかどうかを確認します。しかしif
ステートメントは、ゼロを と同じfalse と見なすので、このチェックを避けて直接書くことができます。
if (substr_count($a, 'are')) {
notであるかどうかを確認するには、!
演算子を追加します。
if (!substr_count($a, 'are')) {
たぶん、あなたはこのような何かを使うことができました:
<?php
findWord('Test all OK');
function findWord($text) {
if (strstr($text, 'ok')) {
echo 'Found a Word';
}
else
{
echo 'Did not find a Word';
}
}
?>
ある文字列が別の文字列に含まれているかどうかだけを確認したい場合は、preg_match()
を使用しないでください。高速になるので、代わりにstrpos()
またはstrstr()
を使用してください。 ( http://in2.php.net/preg_match )
if (strpos($text, 'string_name') !== false){
echo 'get the string';
}
文字列に複数の具体的な単語が含まれているかどうかを確認したい場合は、次のようにします。
$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";
}
これは、たとえば電子メールを送信するときにスパムを回避するのに役立ちます。
Strposはインデックス値として0を返すことがあるため、同一または同一でない演算子を使用する必要があります。三項演算子が好きなら、以下を使うことを検討してください(少し後退しているように思えます):
echo FALSE === strpos($a,'are') ? 'false': 'true';
Strpos関数は問題なく動作しますが、段落内のWordをcase-insensitive
チェックしたい場合は、stripos
のPHP
関数を使用できます。
例えば、
$result = stripos("I love PHP, I love PHP too!", "php");
if ($result === false) {
// Word does not exist
}
else {
// Word exists
}
文字列内で大文字と小文字を区別しないサブストリングの最初の出現位置を見つけます。
Wordが文字列に存在しない場合はfalseを返します。それ以外の場合はWordの位置を返します。
文字列に特定の単語が含まれているかどうかを確認しますか?
これは、文字列を単語に解決する必要があることを意味します(下記の注を参照)。
これを行い、区切り文字を指定する1つの方法は、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'
注: ここで、シンボルのすべてのシーケンスに対してWordという意味ではありません。
Wordの実際的な定義は、PCRE正規表現エンジンという意味です。ここで、単語はWord以外の文字で区切られた、Wordの文字のみで構成される部分文字列です。
「Word」文字は、任意の文字、数字、またはアンダースコア文字、つまりPerlの「Word」の一部になることができる任意の文字です。文字と数字の定義はPCREの文字テーブルによって制御され、ロケール固有のマッチングが行われている場合は異なる場合があります(..)
文字列は以下の関数で確認できます。
function either_String_existor_not($str, $character) {
if (strpos($str, $character) !== false) {
return true;
}
return false;
}
特定の文字列に対する別の解決策:
$subject = 'How are you?';
$pattern = '/are/';
preg_match($pattern, $subject, $match);
if ($match[0] == 'are') {
echo true;
}
strpos()
関数も使えます。
つかいます:
$text = 'This is a test';
echo substr_count($text, 'is'); // 2
// So if you want to check if is exists in the text just put
// in a condition like this:
if (substr_count($text, 'is') > 0) {
echo "is exists";
}
もっと簡単なオプション:
return ( ! empty($a) && strpos($a, 'are'))? true : false;
良いアイデアはmb_stpos
を使うことだと思います:
$haystack = 'How are you?';
$needle = 'are';
if (mb_strpos($haystack, $needle) !== false) {
echo 'true';
}
この解決法は大文字と小文字を区別とすべてのUnicode文字に対して安全であるためです。
しかし、次のようにすることもできます( このような応答はまだ行われていません )。
if (count(explode($needle, $haystack)) > 1) {
echo 'true';
}
この解決法は大文字と小文字を区別するとUnicode文字に対して安全でもあります。
さらにあなたは式の中で否定を使わないでください、これはコードの読みやすさを増すです。
これは他の解決法です関数を使う:
function isContainsStr($haystack, $needle) {
return count(explode($needle, $haystack)) > 1;
}
if (isContainsStr($haystack, $needle)) {
echo 'true';
}
つかいます:
$a = 'How are you?';
if (mb_strpos($a, 'are')) {
echo 'true';
}
マルチバイトセーフなstrpos()操作を実行します。
組み込み関数 strchr()
および strrchr()
、およびマルチバイト文字列の拡張 mb_strchr()
および mb_strrchr()
を使用することもできます。これらの関数は文字列の一部を返し、何も見つからなければFALSE
を返します。
strchr()
- 文字列の最初の出現箇所を検索します( strstr()
のエイリアスです)。strrchr()
- 文字列内で最後に出現した文字を見つけます。