Regex/PHP检查字符组是否只出现一次


Regex/PHP check if group of characters appears only once

我正在尝试用REGEX验证PHP中的输入。我想检查输入中是否有%s字符组,以及它是否只出现一次。否则,该规则将失败。

以下是我尝试过的:

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

我相信这是一个非常简单的解决方案,但我并不真正喜欢REGEX。。。谢谢你的帮助!

如果我理解你的问题,你需要积极的展望。前瞻性导致表达式只有在找到单个%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}]*$正则表达式的其余部分还会查看整个字符串,并确保整个字符串仅由字符类中的字符组成(与原始正则表达式类似)。

我使用PHP的substra_count()函数完成了这项工作,遵循Johnyweb的建议,使用另一种方法来执行验证,因为REGEX的建议看起来相当复杂。

再次感谢!

或者,您可以将preg_match_all与您的模式一起使用,并检查匹配的数量。如果是1,那么你就没事了——类似这样的东西:

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

试试这个:

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

方括号内的(%s){1}序列可能不会起到你认为的作用,但没关系,解决方案更复杂。事实上,{1}不应该出现在正则表达式中的任何位置。它并不能像许多人所认为的那样,确保某件事只有一件。事实上,它对没有任何作用;这纯粹是一团糟。


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

当先行表达式的这一部分退出匹配时,字符串中的下一个必须是%s。然后第二个CCD_ 16开始确认在字符串结束之前没有更多的CCD_。

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

如果你不"喜欢"正则表达式,为什么不用PHP解决这个问题?

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

这会让你更容易阅读,也让其他人更容易维护。