Uza*_*jid 2 javascript php regex pcre
我正在使用PHP的过滤器函数(具体为FILTER_VALIDATE_REGEXP)来验证输入数据.我有一个选项列表,$ input变量可以从列表中指定多个选项.
选项是(不区分大小写):
$ input变量几乎可以包含任何值的组合.可能的成功案例是:
all 或以逗号分隔的其他值列表,但不能同时包含两者)all)我能想出的正则表达式是:
/^(?:all|(?:checkin|verified_checkin|rewards|join|promotions|stream)?(?:,(?:checkin|verified_checkin|rewards|join|promotion|stream))*)$/
Run Code Online (Sandbox Code Playgroud)
到目前为止,它适用于以下示例场景:
all (通过)rewards,join,promotion,checkin,verified_checkin (通过)join (通过)但是,它允许带有前导逗号的值并通过以下方式重复:
,promotion,checkin,verified_checkin (以逗号开头但在不应该的时候也会传递)此外,检查重复项将是一个奖励,但不一定是必需的.
rewards,join,promotion,checkin,join,verified_checkin (重复值但仍然通过,但不像主要逗号那么重要)我已经在这里工作了几天并尝试了各种实现,这是我能够得到的最接近的.
关于如何处理领先逗号误报的任何想法?
更新:编辑问题以更好地解释重复过滤不是真正的要求,只是奖金.
有时正则表达式会让事情变得更加复杂.正则表达式非常擅长匹配模式,但是当您引入依赖于匹配模式数量的外部规则时,事情会变得很复杂.
在这种情况下,我只是将列表拆分为逗号,并根据您刚才描述的规则检查生成的字符串.
$valid_choices = array('checkin','join','promotions','rewards','stream','verified_checkin');
$input_string; // string to match
$tokens = explode(',' $input_string);
$tokens = asort($tokens); // sort to tokens to make it easy to find duplicates
if($tokens[0] == 'all' && count($tokens) > 1)
return FALSE; // fail (all + other options)
if(!in_array($tokens[0], $valid_choices))
return FALSE; // fail (invalid first choice)
for($i = 1; $i < count($tokens); $i++)
{
if($tokens[$i] == $tokens[$i-1])
return FALSE; // fail (duplicates)
if(!in_array($tokens[$i], $valid_choices))
return FALSE; // fail (choice not valid)
}
Run Code Online (Sandbox Code Playgroud)
编辑
既然您编辑了并指定了重复项是可以接受的,但您肯定需要基于正则表达式的解决方案,那么这个应该做:
^(all|((checkin|verified_checkin|rewards|join|promotions|stream)(,(checkin|verified_checkin|rewards|join|promotion|stream))*))$
Run Code Online (Sandbox Code Playgroud)
它不会在重复上失败,但它会照顾或引导或尾随逗号,或所有+其他选择组合.
使用正则表达式过滤重复项将非常困难,但也许并非不可能(如果您使用捕获组占位符预测)
第二次编辑
虽然您提到检测重复条目并不重要,但我想我会尝试制作一个也可以检查重复条目的模式.
正如您在下面看到的那样,它不是很优雅,也不是很容易扩展,但它确实可以通过使用负面预测的有限选项列表来完成工作.
^(all|(checkin|verified_checkin|rewards|join|promotions|stream)(,(?!\2)(checkin|verified_checkin|rewards|join|promotions|stream))?(,(?!\2)(?!\4)(checkin|verified_checkin|rewards|join|promotions|stream))?(,(?!\2)(?!\4)(?!\6)(checkin|verified_checkin|rewards|join|promotions|stream))?(,(?!\2)(?!\4)(?!\6)(?!\8)(checkin|verified_checkin|rewards|join|promotions|stream))?(,(?!\2)(?!\4)(?!\6)(?!\8)(?!\10)(checkin|verified_checkin|rewards|join|promotions|stream))?)$
Run Code Online (Sandbox Code Playgroud)
由于最终的正则表达式是如此之长,我将把它分解为部分,以便更容易遵循一般的想法:
^(all|
(checkin|verified_checkin|rewards|join|promotions|stream)
(,(?!\2)(checkin|verified_checkin|rewards|join|promotions|stream))?
(,(?!\2)(?!\4)(checkin|verified_checkin|rewards|join|promotions|stream))?
(,(?!\2)(?!\4)(?!\6)(checkin|verified_checkin|rewards|join|promotions|stream))?
(,(?!\2)(?!\4)(?!\6)(?!\8)(checkin|verified_checkin|rewards|join|promotions|stream))?
(,(?!\2)(?!\4)(?!\6)(?!\8)(?!\10)(checkin|verified_checkin|rewards|join|promotions|stream))?
)$/
Run Code Online (Sandbox Code Playgroud)
你可以看到形成模式的机制有点迭代,如果你想提供一个不同的列表,但是这样的模式可以由算法自动生成,但结果模式会变得相当大,相当快.
| 归档时间: |
|
| 查看次数: |
1015 次 |
| 最近记录: |