正则表达式/ PHP检查字符组是否只出现一次

时间:2011-06-23 20:51:24

标签: php regex validation

我正在尝试使用REGEX验证PHP中的输入。我想检查输入中是否包含%s字符组,并且只显示一次。否则,规则应该失败。

这是我尝试过的:

preg_match('|^[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value);(除此之外还有一些其他规则;我已经尝试了(%s){1}部分,但它不起作用。)

我相信这是一个非常简单的解决方案,但我并没有真正进入REGEX ......谢谢你的帮助!

5 个答案:

答案 0 :(得分:4)

如果我理解你的问题,你需要一个积极的前瞻。前瞻导致表达式仅在找到单个%s时才匹配。

preg_match('|^(?=[^%s].*?[%s][^%s]*$)[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value);

我将解释每个部分的工作原理

^(?=[^%s].*?[%s][^%s]*$)是零宽度断言 - (?=regex)是一个积极的先行 - (意味着它必须匹配,但不会“吃掉”任何字符)。这意味着整行只能有1 %s

[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$正则表达式的剩余部分也会查看整个字符串,并确保整个字符串仅由字符类中的字符组成(就像您的原始正则表达式一样)。

答案 1 :(得分:2)

我设法用PHP的substr_count()函数执行此操作,遵循 Johnsyweb 建议使用替代方法执行验证,因为REGEX的建议看起来相当复杂。

再次感谢你!

答案 2 :(得分:1)

或者,您可以在模式中使用preg_match_all并检查匹配数量。如果它是1,那么你没事 - 就像这样:

$result = (preg_match_all('|^[0-9a-zA-Z_-\s:;,\.\?!\(\)\p{L}(%s){1}]*$|u', $value) == 1)

答案 3 :(得分:1)

试试这个:

'|^(?=(?:(?!%s).)*%s(?:(?!%s).)*$)[0-9_\s:;,.?!()\p{L}-]+$|u'

方括号内的(%s){1}序列可能不会按照您的想法执行,但不要紧,解决方案更复杂。实际上,{1}永远不会出现在正则表达式中的任何位置。它不能确保只有一个东西,正如许多人所认为的那样。事实上,它没有任何;这是纯粹的混乱。


编辑(回答评论):为了确保字符串中只存在一个特定序列,您必须主动检查每个字符,将其分类为%s的部分或部分 - %s。为此,(?:(?!%s).)*一次消耗一个字符,之后否定前瞻已确认该字符不是%s的开头。

当前瞻表达式的那一部分退出匹配时,字符串中的下一个内容必须是%s。然后第二个(?:(?!%s).)*$开始确认在字符串结束之前不再有%s个序列。

不要忘记,前瞻表达式必须锚定在两端。因为前瞻是主正则表达式的起始锚之后的第一件事,所以你不需要添加另一个^。但是前瞻必须以自己的$锚结束。

答案 4 :(得分:0)

如果你没有“进入”正则表达式,为什么不用PHP解决这个问题?

对内置strpos()的一次调用将告诉您字符串是否匹配。第二个电话会告诉您它是否出现不止一次。

这将使您更容易阅读和维护其他人。