1.) Для того, чтобы просто удалить один из стоп-словначала или конца строки с помощью regex like this:
~^\W*(der|die|das|the)\W+\b|\b\W+(?1)\W*$~i
~
является pattern delimiter
^
каретка anchor начало матчей строка
\W
(верхний) является short для символа, который не является word character
(der|die|das|the)
Чередования |
в первых скобках group
\b
соответствует word boundary
- В
(?1)
структура первой группы наклеивается
$
матчей правильных после последнего символа в строке
- Подержанный
i
(PCRE_CASELESS)flag. Если вводится utf-8, также необходимо u
(PCRE_UTF8) флаг.
Reference - What does this regex mean
Генерация шаблона:
// array containing stopwords
$stopwords = array("der", "die", "das", "the");
// escape the stopword array and implode with pipe
$s = '~^\W*('.implode("|", array_map("preg_quote", $stopwords)).')\W+\b|\b\W+(?1)\W*$~i';
// replace with emptystring
$searchString = preg_replace($s, "", $searchString);
Примечание что если ~
разделителем происходит в $stopwords
массиве, он также должен быть экранированы с обратной косой черты.
PHP test at eval.in, Regex pattern at regex101
2.) Но удалить стоп-слова в любом месте строки как насчет разделения на слова:
// words to be removed
$stopwords = array(
'der' => 1,
'die' => 1,
'das' => 1,
'the' => 1);
# used words as key for better performance
// remove stopwords from string
function strip_stopwords($str = "")
{
global $stopwords;
// 1.) break string into words
// [^-\w\'] matches characters, that are not [0-9a-zA-Z_-']
// if input is unicode/utf-8, the u flag is needed: /pattern/u
$words = preg_split('/[^-\w\']+/', $str, -1, PREG_SPLIT_NO_EMPTY);
// 2.) if we have at least 2 words, remove stopwords
if(count($words) > 1)
{
$words = array_filter($words, function ($w) use (&$stopwords) {
return !isset($stopwords[strtolower($w)]);
# if utf-8: mb_strtolower($w, "utf-8")
});
}
// check if not too much was removed such as "the the" would return empty
if(!empty($words))
return implode(" ", $words);
return $str;
}
См demo at eval.in, ideone.com
// test it
echo strip_stopwords("The Hobbit das foo, der");
Хоббит Foo
Это решение также удалите любые знаки препинания, кроме _
-
'
, потому что он уничтожает оставшиеся слова с пробелом после удаления общих слов. Идея состоит в том, чтобы подготовить строку для запроса.
Оба решения не изменяют корпус и оставляют строку, если она состоит только из за одно мгновение.
Списки общих слов
Этот тест 'strlen ($ searchString)> strlen ($ article)' абсолютно бесполезен, удалите его. 'strpos' может возвращать 0, которое интерпретируется как false. Вы должны написать 'strpos (...)! == false'. Вместо того, чтобы делать тесты, замените их напрямую. таким образом вы разбираете строку только один раз. –
Преимущество использования 'preg_replace' здесь заключается в том, чтобы избежать ложных срабатываний с использованием границ слов для разграничения слов и для удаления всех из них за один проход с использованием чередования. Шаблон не является сложным, быстрое руководство по регулярному выражению решит проблему. –
Я попытался '$ optimizedString = preg_replace ("/(der \ s | die \ s | das \ s | the \ s)/", '', $ searchString);' но это, похоже, не сработает ... – bambamboole