Подстрока PHP, совпадающая с целыми словами - PullRequest
0 голосов
/ 08 октября 2018

Я пытаюсь написать функцию StringMatch, которая возвращает истину, когда слова из одной строки можно найти в другой строке.Исключением является то, что я не хочу совпадений с такими вещами, как множественное число и другие суффиксы, и я также хотел бы избегать сопоставления, когда слово имеет префикс.

Чтобы объяснить более наглядно:

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 (), но он недостаточно строг для моих нужд.

Ответы [ 2 ]

0 голосов
/ 08 октября 2018
  • Прежде всего, регулярное выражение не всегда является лучшим решением.Regex нуждается в компиляции.
  • Во-вторых, вы можете разбить слово на основе пробела, и теперь у вас есть массив отдельных слов.Используйте in_array () и проверьте каждое слово в стоге сена.

КОД:

<?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");
0 голосов
/ 08 октября 2018

Как я уже говорил в комментариях

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 Цитата необходимо избегатьпроблемы, в которых $str1 может содержать такие вещи, как ., в Regex - любой символ.

Кроме того, вы можете убрать знаки препинания следующим образом

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

Например:

echo StringMatch("apple watch.", "apple watch repairs"); // output 1

Без удаления пунктуации это вернет 0. Скорее всего, это не ваше дело.

Песочница

ОБНОВЛЕНИЕ

Совпадение не по порядку, например:

//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_replace

 $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).То есть, если вам важно, чтобы все слова совпадали.

...