我想在php中获得正则表达式的最小匹配。RegExp PHP显示最小的匹配
例如:如果我有文字电视和电话,用户输入是电话,我的正则表达式应返回最小的单词,在这种情况下,电话。 简而言之,我试图像搜索脚本一样。但是对于用户输入中缺少的字母,我使用这个t[a-zA-Z0-9]{0,2}l[a-zA-Z0-9]{0,}
,所以我的最后一个字母形成单词后面会跟着N个字符。
我的问题是:我如何做我的REGEXP显示最小的单词。
我想在php中获得正则表达式的最小匹配。RegExp PHP显示最小的匹配
例如:如果我有文字电视和电话,用户输入是电话,我的正则表达式应返回最小的单词,在这种情况下,电话。 简而言之,我试图像搜索脚本一样。但是对于用户输入中缺少的字母,我使用这个t[a-zA-Z0-9]{0,2}l[a-zA-Z0-9]{0,}
,所以我的最后一个字母形成单词后面会跟着N个字符。
我的问题是:我如何做我的REGEXP显示最小的单词。
不幸的是,你不能这样做。正则表达式可以匹配你想要的,但是它不提供任何函数来比较子匹配。你必须匹配你的整个字符串,并在你的情况下通过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;
我认为你可以使用正则表达式实现这一目标的唯一途径,就是在希望的顺序词第一,排序在你的情况下,从短到长。
然后,如果您的单词数量相对较少,为了表现,可以将单词连接起来并同时检查第一个匹配项。这是可能的,因为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;
}
当然,它不是最有效的算法,可能会以多种方式进行改进。但为了完成这个关于所需范围和使用的更多信息。
正则表达式引擎通常既没有预期的内存来存储复杂的条件,也没有提供复杂的比较的编程语言功能的好处。
如果标记php没有漫无目的地完成,你可以用更多的行来完成你的工作。
$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];
@woo感谢您的回答。这对我帮助很大 。干杯! –
正则表达式不能自己做到这一点。你必须找到所有匹配的正则表达式,然后按照长度排序并显示第一个。 – Barmar
您可能需要一些代码,例如您正在搜索的内容和方式。 – AbraCadaver