【问题标题】:Regex/PHP check if group of characters appears only once正则表达式/PHP检查字符组是否只出现一次
【发布时间】:2011-06-23 20:51:24
【问题描述】:

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

这是我尝试过的:

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

我相信这是一个非常简单的解决方案,但我不是很喜欢正则表达式...谢谢你的帮助!

【问题讨论】:

  • 鉴于你自己的答案,我建议这个问题的标题不正确。
  • 更改了标题以反映我的回答。

标签: php regex validation


【解决方案1】:

如果我理解您的问题,您需要积极向前看。前瞻使表达式仅在找到单个 %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}]*$ 正则表达式的其余部分也会查看整个字符串,并确保整个字符串仅由字符类中的字符组成(就像您的原始正则表达式一样)。

【讨论】:

  • 你能解释一下你添加的代码是什么吗?看起来很复杂:)
  • @linkyndy,我已经添加了解释。如果需要,请随时要求进一步澄清。祝你好运。
  • 感谢您的澄清。现在看起来更清楚了,但我仍然相信我需要练习 REGEX。因此,我现在将坚持使用substr_count() 解决方案。再次感谢!
【解决方案2】:

我设法通过 PHP 的 substr_count() 函数做到了这一点,遵循 Johnsyweb 建议使用另一种方法来执行验证,并且因为 REGEX 的建议看起来相当复杂。

再次感谢您!

【讨论】:

  • 这比我的回答要好得多!我不是 PHP 开发人员,我只是偶然发现了这个问题,因为它被标记为 [regex]。
【解决方案3】:

或者,您可以将preg_match_all 与您的模式一起使用并检查匹配数。如果它是 1,那么你没问题 - 像这样:

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

【讨论】:

    【解决方案4】:

    试试这个:

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

    方括号内的(%s){1} 序列可能不会像您认为的那样做,但没关系,解决方案更复杂。事实上,{1} 不应该出现在正则表达式的任何地方。正如许多人所认为的那样,它并不能确保只有其中之一。事实上,它什么都不做;这纯粹是混乱。


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

    当前瞻表达式的那部分退出匹配时,字符串中的下一个内容必须是%s。然后第二个(?:(?!%s).)*$ 开始确认直到字符串末尾没有更多的%s 序列。

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

    【讨论】:

    • 谢谢,但你能解释一下我现有的正则表达式之前的所有序列是什么吗?我认为这将是一个简单的解决方案,但它似乎非常复杂。
    • 好的,我在答案中添加了解释。
    • 哦,所以这不是很容易,但我想我设法理解了这个想法。感谢您的澄清。我肯定需要更多的 REGEX 练习......但在那之前,我会坚持使用 substr_count() 的解决方案。
    【解决方案5】:

    如果您不“喜欢”正则表达式,为什么不使用 PHP 解决这个问题?

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

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

    【讨论】:

    • 我的整个验证由正则表达式组成,我希望将每个规则放在一行中,而不是分散在几个代码块中。
    • 这就是 functions 的用途!
    猜你喜欢
    • 2021-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多