匹配整词的PHP子字符串

匹配整词的PHP子字符串,php,regex,strpos,Php,Regex,Strpos,我正在尝试编写一个StringMatch函数,当一个字符串中的单词可以在另一个字符串中找到时,该函数将返回true。例外情况是,我不希望复数和其他后缀匹配,而且我还希望避免在单词加前缀时匹配 要更直观地解释: apple watch - apple watches (no match) apple watch - apple watch repairs (match) apple watch - new apple watch (match) apple watch - pineapple wa

我正在尝试编写一个StringMatch函数,当一个字符串中的单词可以在另一个字符串中找到时,该函数将返回true。例外情况是,我不希望复数和其他后缀匹配,而且我还希望避免在单词加前缀时匹配

要更直观地解释:

apple watch - apple watches (no match)
apple watch - apple watch repairs (match)
apple watch - new apple watch (match)
apple watch - pineapple watch (no match)
我想说的是:

echo StringMatch("apple watch", "apple watches");       // output 0
echo StringMatch("apple watch", "apple watch repairs"); // output 1
echo StringMatch("apple watch", "new apple watch");     // output 1
echo StringMatch("apple watch", "pineapple watch");     // output 0
我在strpos()方面取得了一些基本的成功。根据上面的示例,当第二个字符串包含后缀或前缀时,我不知道如何返回“0”

以下是我试图解决这个问题的方法:

function StringMatch($str1,$str2)
{
    if (SomeFunctionOrRegex($str1,$str2) !== false)
    {
        return(1);
    }
    else
    {
        return(0);
    }
}

也许有一个优雅的正则表达式解决方案。我试过strpos(),但它对我的需求不够严格。

就像我在评论中说的那样

function StringMatch($str1,$str2)
{
  return preg_match('/\b'.preg_quote($str1,'/').'\b/i', $str2);
}

echo StringMatch("apple watch", "apple watches");       // output 0
echo "\n";
echo StringMatch("apple watch", "apple watch repairs"); // output 1
echo "\n";
echo StringMatch("apple watch", "new apple watch");     // output 1
echo "\n";
echo StringMatch("apple watch", "pineapple watch");     // output 0
echo "\n";
输出:

0
1
1
0

Preg Quote in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in in REQUOTE in in REQUOTE in REQUOTE in REQUOTE in Regex中的
可能包含类似于
的任何字符

此外,你可以像这样去掉标点符号

$str1 = preg_replace('/[^\w\s]+/', '', $str1);
例如:

echo StringMatch("apple watch.", "apple watch repairs"); // output 1
//words out of order
echo StringMatch("watch apple", "new apple watch");     // output 1
如果不删除标点符号,将返回0。重要与否取决于你自己

更新

无序匹配,例如:

echo StringMatch("apple watch.", "apple watch repairs"); // output 1
//words out of order
echo StringMatch("watch apple", "new apple watch");     // output 1
简单的方法是内爆/爆炸:

function StringMatch($str1,$str2)
{
  //use one or the other
  $str1 = preg_replace('/[^\w\s]+/', '', $str1);
  //$str1 = preg_quote($str1,'/');
  $words = explode(' ', $str1);
  preg_match_all('/\b('.implode('|',$words).')\b/i', $str2,     $matches);
  return count($words) == count($matches[0]) ? '1' : '0';
}

也可以跳过“分解/内爆”并使用

 $str1 = preg_replace('/\s/', '|', $str1);
可与其他preg_替换组合

 $str1 = preg_replace(['/[^\w\s]+/','/\s/'], ['','|'], $str1);
还是全部

function StringMatch($str1,$str2)
{
  $str1 = preg_replace(['/[^\w\s]+/','/\s/'], ['','|'], $str1);
  preg_match_all('/\b('.$str1.')\b/i', $str2, $matches);
  return (substr_count($str1, '|')+1) == count($matches[0]) ? '1' : '0';
}


当然,你不能计算单词数组,但是你可以计算
|
管道的数量,它比单词的数量少1(因此是+1)。如果你关心所有的单词是否匹配的话。

就像我在评论中说的那样

function StringMatch($str1,$str2)
{
  return preg_match('/\b'.preg_quote($str1,'/').'\b/i', $str2);
}

echo StringMatch("apple watch", "apple watches");       // output 0
echo "\n";
echo StringMatch("apple watch", "apple watch repairs"); // output 1
echo "\n";
echo StringMatch("apple watch", "new apple watch");     // output 1
echo "\n";
echo StringMatch("apple watch", "pineapple watch");     // output 0
echo "\n";
输出:

0
1
1
0

Preg Quote in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in REQUOTE in in REQUOTE in REQUOT

此外,你可以像这样去掉标点符号

$str1 = preg_replace('/[^\w\s]+/', '', $str1);
例如:

echo StringMatch("apple watch.", "apple watch repairs"); // output 1
//words out of order
echo StringMatch("watch apple", "new apple watch");     // output 1
如果不删除标点符号,将返回0。重要与否取决于你自己

更新

无序匹配,例如:

echo StringMatch("apple watch.", "apple watch repairs"); // output 1
//words out of order
echo StringMatch("watch apple", "new apple watch");     // output 1
简单的方法是内爆/爆炸:

function StringMatch($str1,$str2)
{
  //use one or the other
  $str1 = preg_replace('/[^\w\s]+/', '', $str1);
  //$str1 = preg_quote($str1,'/');
  $words = explode(' ', $str1);
  preg_match_all('/\b('.implode('|',$words).')\b/i', $str2,     $matches);
  return count($words) == count($matches[0]) ? '1' : '0';
}

也可以跳过“分解/内爆”并使用

 $str1 = preg_replace('/\s/', '|', $str1);
可与其他preg_替换组合

 $str1 = preg_replace(['/[^\w\s]+/','/\s/'], ['','|'], $str1);
还是全部

function StringMatch($str1,$str2)
{
  $str1 = preg_replace(['/[^\w\s]+/','/\s/'], ['','|'], $str1);
  preg_match_all('/\b('.$str1.')\b/i', $str2, $matches);
  return (substr_count($str1, '|')+1) == count($matches[0]) ? '1' : '0';
}

当然,你不能计算单词数组,但是你可以计算
|
管道的数量,它比单词的数量少1(因此是+1)。如果你关心所有的单词是否匹配的话。

  • 首先,正则表达式并不总是最好的解决方案。正则表达式需要编译
  • 其次,您可以根据空间分割单词,现在您有了一个单个单词的数组。使用并检查干草堆中的每个单词
代码:

<?php

function StringMatch($needle,$haystack){
    $domain_of_words = explode(" ",$haystack);
    $words = explode(" ",$needle);
    foreach($words as $each_word){
        if(!in_array($each_word,$domain_of_words,true)){
            return 0;
        }
    }
    return 1;
}

echo StringMatch("apple watch","apple watches repairs"),"<br/>";
echo StringMatch("apple watch","apple watch repairs");
  • 首先,正则表达式并不总是最好的解决方案。正则表达式需要编译
  • 其次,您可以根据空间分割单词,现在您有了一个单个单词的数组。使用并检查干草堆中的每个单词
代码:

<?php

function StringMatch($needle,$haystack){
    $domain_of_words = explode(" ",$haystack);
    $words = explode(" ",$needle);
    foreach($words as $each_word){
        if(!in_array($each_word,$domain_of_words,true)){
            return 0;
        }
    }
    return 1;
}

echo StringMatch("apple watch","apple watches repairs"),"<br/>";
echo StringMatch("apple watch","apple watch repairs");

$str1
的每一侧添加分词断言,
\b
,并使用正则表达式。
preg\u match('/\b).preg\u quote($str1'/')。\b/i',$str2)
strps()
由于使用错误的原因而无效。请参见此处,在
$str1
的两侧添加分词断言,
\b
,并使用正则表达式。
preg\u match('/\b'.preg\u quote($str1'/')。\b/i',$str2)
strpos()
由于使用错误的原因而无效。请参见此处,如果您使用
preg\u match\u all
和单词之间带有
(管道)的捕获组,您可以将它们无序匹配。谢谢@ArtisticPhoenix我得到了我想要的以及更多。如果您使用
preg\u match\u all
和带有
(管道)的捕获组,您可以将它们无序匹配字里行间。谢谢@ArtisticPhoenix我得到了我想要的,还有更多。