我还在玩一个有匹配词的项目。
假设我有一个给定的字符串,比如 maxmuster 。然后我想在 maxmuster 中标记随机字 maxs 的 部分>按照正确的顺序,就像字母一样。
我会举一些例子然后告诉我已经做过的事情。让我们保持字符串 maxmuster 。粗体部分是由正则表达式匹配的(最好是在php中,但可能是python,bash,javascript,...)
最大取值
我的 maxmu 是
勒的亩
鼓起
当然 m ,你,......也会匹配。我知道,我稍后会解决这个问题。但是,我的解决方案应该不会那么困难,所以我尝试将这个词分成这样的组:
/(maxmuster)?|(maxmuste)?|(maxmust)?|(maxmus)?|(maxmu)?|(maxm)?|(max)?|(ma)?|(m)?/gui
但后来我忘了其他组合,比如:
(axmuster)(xmus)
等等。我是否真的必须这样做,或者存在一个简单的正则表达技巧来解决这个问题,就像我上面解释过的那样?
非常感谢
答案 0 :(得分:2)
听起来你需要字符串交集。如果您不介意非正则表达式的想法,请查看Wikibooks Algorithm Implementation/Strings/Longest common substring PHP部分。
foreach(["maxs", "Mymaxmuis", "Lemu", "muster"] AS $str)
echo get_longest_common_subsequence($str, "maxmuster") . "\n";
最大
maxmu
亩
鼓起
See this demo at eval.in(无壳比较)。
答案 1 :(得分:1)
使用正则表达式:
longestSubstring(['Mymaxmuis', 'axmuis', 'muster'], buildRegexFrom('maxmuster'));
使用下面的正则表达式,您可以匹配字符串maxmuster
的所有真实子字符串:
(?|((?:
m(?=a)
|(?<=m)a
|a(?=x)
|(?<=a)x
|x(?=m)
|(?<=x)m
|m(?=u)
|(?<=m)u
|u(?=s)
|(?<=u)s
|s(?=t)
|(?<=s)t
|t(?=e)
|(?<=t)e
|e(?=r)
|(?<=e)r
)+)|([maxmuster]))
<强> Live demo 强>
你必须从像maxmuster
这样的单词中制作这样的正则表达式,所以你需要一个函数来调用它:
function buildRegexFrom(string $word): string {
// Split word to letters
$letters = str_split($word);
// Creating all side of alternations in our regex
foreach ($letters as $key => $letter)
if (end($letters) != $letter)
$regex[] = "$letter(?={$letters[$key + 1]})|(?<=$letter){$letters[$key + 1]}";
// Return whole cooked pattern
return "~(?|((?>".implode('|', $regex).")+)|([$word]))~i";
}
要返回最长匹配,您需要根据从最长到最短的匹配长度对结果进行排序。这意味着为它编写另一段代码:
function longestSubstring(array $array, string $regex): array {
foreach ($array as $value) {
preg_match_all($regex, $value, $matches);
usort($matches[1], function($a, $b) {
return strlen($b) <=> strlen($a);
});
// Store longest match being sorted
$substrings[] = $matches[1][0];
}
return $substrings;
}
把所有事情放在一起:
print_r(longestSubstring(['Mymaxmuis', 'axmuis', 'muster'], buildRegexFrom('maxmuster')));
输出:
Array
(
[0] => maxmu
[1] => axmu
[2] => muster
)
<强> PHP live demo 强>
答案 2 :(得分:0)
以下是我使用正则表达式解决此问题的方法。
<?php
$subject="maxmuster";
$str="Lemu";
$comb=str_split($subject); // Split into single characters.
$len=strlen($subject);
for ($i=2; $i<=$len; $i++){
for($start=0; $start<$len; $start++){
$temp="";
$inc=$start;
for($j=0; $j<$i; $j++){
$temp=$temp.$subject[$inc];
$inc++;
}
array_push($comb,$temp);
}
}
echo "Matches are:\n";
for($i=0; $i<sizeof($comb); $i++){
$pattern = "/".$comb[$i]."/";
if(preg_match($pattern,$str, $matches)){
print_r($matches);
};
}
?>
这是 Ideone Demo 。