регулярное выражение — RegExp PHP показать наименьшее совпадение

Я пытаюсь получить наименьшее совпадение регулярного выражения в php.

Например: Если у меня есть слова «телевидение» и «телефон», а пользователь вводит «тел», мое регулярное выражение должно возвращать наименьшее слово, в данном случае «телефон».
Для краткости я пытаюсь сделать как поисковый скрипт. Но для букв, пропущенных в пользовательском вводе, я использую это t[a-zA-Z0-9]{0,2}l[a-zA-Z0-9]{0,} поэтому моя последняя буква формы слова будет сопровождаться N символов.

Мой вопрос: как я могу сделать мой REGEXP, чтобы показать самое маленькое слово.

0

Решение

К сожалению, вы не можете сделать это. Regex может соответствовать тому, что вы хотите, но он не предоставляет никаких функций для сравнения подсовпадений. Вы должны сопоставить всю строку и сравнить подстроки по коду PHP в вашем случае.

// your array of matched words
$words = array(...);

$foundWordLength = null;
$foundWord = '';

foreach ($words as $word) {
if (strlen($word) < $foundWordLength || $foundWordLength === null) {
$wordLength = strlen($word);
$foundWord = $word;
}
}

echo $foundWord;
1

Другие решения

Я думаю, что единственный способ добиться этого с помощью регулярных выражений — это сначала отсортировать слова в желаемом порядке, в вашем случае — от самого короткого до самого длинного.

Тогда, если у вас есть относительно небольшое количество слов, для эффективности слова могут быть объединены и проверены на первое совпадение одновременно. Это возможно, потому что реализация PHP RegExp выполняет поиск слева направо. Смотрите функцию search_short() в примере ниже.

В любом случае, цикл и проверка слова, начиная с самого низкого, также будут работать. Проверьте функцию search_long() в примере ниже.

<?php
$given = [
'telephone',
'television',
];
// NB: Do not forget to sanitize user input, i.e. $query
echo (search_short($given, 'tele') ?: 'Nothing found') . PHP_EOL;
echo (search_long($given, 'tele') ?: 'Nothing found') . PHP_EOL;
echo (search_short($given, 't[a-zA-Z0-9]{0,2}l[a-zA-Z0-9]{0,}') ?: 'Nothing found') . PHP_EOL;
echo (search_long($given, 't[a-zA-Z0-9]{0,2}l[a-zA-Z0-9]{0,}') ?: 'Nothing found') . PHP_EOL;

/**
* @param string[] $given
* @param string   $query
*
* @return null|string
*/
function search_short($given, $query)
{

// precalculating the length of each word, removing duplicates, sorting
$given = array_map(function ($word) {
return mb_strlen($word); // `mb_strlen()` is O(N) function, while `strlen()` is O(1)
}, array_combine($given, $given));
asort($given);

// preparing the index string
$index = implode(PHP_EOL, array_keys($given));
// and, finally, searching (the multiline flag is set)
preg_match(
sprintf('/^(?<word>%s\w*)$/mu', $query), // injecting the query word
$index,
$matches
);

// the final pattern looks like: "/^(?P<word>tele\w*)$/mui"if (array_key_exists('word', $matches)) {
return $matches['word'];
}
return null;
}

/**
* @param string[] $given
* @param string   $query
*
* @return null|string
*/
function search_long($given, $query)
{
$pattern = sprintf('/^(?<word>%s\w*)$/u', $query);

// precalculating the length of each word, removing duplicates, sorting
$given = array_map(function ($word) {
return mb_strlen($word);
}, array_combine($given, $given));
asort($given);foreach ($given as $word => $count) {
if (preg_match($pattern, $word, $matches)) {
if (array_key_exists('word', $matches)) {
return $matches['word'];
}
}
}
return false;
}

Конечно, это не самый эффективный алгоритм, и его можно улучшить несколькими способами. Но для этого нужно больше информации о масштабах и использовании.

1

Механизм регулярных выражений обычно не имеет предназначенной памяти для хранения сложных условий и не имеет преимуществ от возможностей языка программирования для обеспечения сложных сравнений.

Вы можете сделать свою работу с еще несколькими строками, если пометить не было сделано бесцельно.

$str = 'television and telephone';
preg_match_all('/tel\w*/', $str, $matches);
usort($matches[0], function($a, $b) {
return strlen($a) <=> strlen($b);
});
echo $matches[0][0];
1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector