我有一些带有字符和字符串列表的输入字符串。我需要的是只选择满足包含字符的模式的字符串。excample:
输入字符= "ask"它应该接受"ask"、"sak"、"kas"……但不应接受"akk", "aas"…
我现在使用模式如"^ [s | | k] [s | | k] [s | | k美元"但是它有可能接受和重复字符("akk"),所以如果我使用这个,我需要一些额外的检查preg_match是否有效。
更复杂的是,可以有几个相同的字符:输入"askk"应该匹配"akks",但不匹配"kkks"或" ask "
我相信这个检查可以用一个regexp来完成,但是我对regexp的了解不是那么深。
(我使用php来获取输入和显示结果)
使用正则表达式实际上很难解决这类问题。如果你有前瞻表达式,你可以这样做。下面是一个示例,其中(?=...)
是一个forward表达式。
/^(?=.*a)(?=.*s)(?=.*k).{3}$/
这里的每个(?=.*a)
表达式匹配该字母,在表达式中的任何位置,并且。{3}指定它必须是三个字符。
当您有重复的字符时,这会变得复杂,但仍然是可能的。对于aask
:
/^(?=.*a.*a)(?=.*s)(?=.*k).{4}$/
只有当字符串中有两个a
时,第一个才匹配。
你可以用一些其他的方法来做这件事。例如,您可以遍历每个字符并计算每个字母的个数,将其存储在数组中(这是O(n)),或者您可以按字母顺序对字符进行排序(aks
)并逐个字符匹配字符串(这是O(无论您的排序算法是什么))。
为什么在这里使用正则表达式?我看不出有什么好处。你可以做的是对输入字符串进行排序(例如'sak'和'ask'都会变成'aks'),并将排序后的字符串与引用字符串进行比较,在这种情况下是'aks'。或者只是在引用字符串'ask'上使用相同的函数。像这样:
function str_sort($str) {
$chars = str_split($str);
sort($chars);
return implode('', $chars);
}
$pattern = 'ask';
$input = 'sak';
$valid = str_sort($pattern) == str_sort($input);
echo "Pattern: $pattern;'n";
echo "Input : $input'n";
echo "Valid : " . ($valid ? 'yes' : 'no') . "'n";
以下是"ask "的解决方案:
^(?=.*a)(?=.*s)(?=(?:.*k){2})[ask]{4}$
其思想是首先使用查找来确保字符串中每个字符的正确数目,然后使用字符串的其余部分,确保只使用提供的字符集中的字符。