【问题标题】:Regular expression to match single dot but not two dots?正则表达式匹配单个点而不是两个点?
【发布时间】:2012-05-27 06:47:37
【问题描述】:

尝试创建用于电子邮件地址检查的正则表达式模式。这将允许一个点 (.),但如果有多个彼此相邻,则不允许。

应该匹配: test.test@test.com

不应匹配: test..test@test.com

现在我知道互联网上有成千上万的电子邮件匹配示例,所以请不要向我发布完整解决方案的链接,我正在尝试在这里学习。

其实我最感兴趣的只是本地部分: 应该匹配的 test.test 和不应该匹配的 test..test。 感谢您的帮助。

【问题讨论】:

  • 规范定义了你应该如何匹配它tools.ietf.org/html/rfc2822#page-17。以这种方式构建健壮的正则表达式比在这里使用只关注 2 个点的问题的临时解决方案要容易得多
  • 实际上我正在经历那个规范......并且遇到了我的第一个障碍,试图学习匹配一个点但不是两个或多个彼此相邻的正则表达式。
  • 好吧,它说本地部分是点原子或引用的字符串,然后您查找点原子是什么,它是 1 个原子文本,后跟一个点和另一个原子文本。这自动是一个正则表达式,它取消以点开头、以点结尾或中间有两个或多个连续点的字符串的资格。为简单起见,假设 atomtext 只是字符 a-z。那么只允许点原子的局部部分是:/^([a-z](?:\.[a-z])*)+$/

标签: php regex pattern-matching


【解决方案1】:

您可以允许任意数量的[^\.](除点之外的任何字符)和[^\.])\.[^\.](由两个非点包围的点)通过在它们之间使用分离(管道符号|)并将在^$ 之间使用*(其中任意数量)的整个内容,以便整个字符串由这些组成。代码如下:

$s1 = "test.test@test.com";
$s2 = "test..test@test.com";
$pattern = '/^([^\.]|([^\.])\.[^\.])*$/';
echo "$s1: ", preg_match($pattern, $s1),"<p>","$s2: ", preg_match($pattern, $s2);

产量:

test.test@test.com: 1
test..test@test.com: 0

【讨论】:

  • 第二部分可能是\.{1}
  • 需要注意的是,这不允许在字符串的末尾和开头使用点
  • 实际上不应该是'/^([^\.]|([^\.]\.[^\.]))*$/' 而不是'/^([^\.]|([^\.])\.[^\.])*$/'? ([^\.]\.[^\.]) 周围的括号,不仅仅是[^\.]
  • @YakovL:没关系,实际上内括号可以省略。括号的优先级低于析取,因此仍然可以正确解析。
【解决方案2】:

这对我来说更合乎逻辑:

/[^.]([\.])[^.]/

而且很简单。前瞻和后瞻确实很有用,因为它们不捕获值。但在这种情况下,捕获组仅在中间点附近。

【讨论】:

  • 如果字符串中的任何位置都有一个点,则它会匹配两个示例。
【解决方案3】:
strpos($input,'..') === false

strpos 函数更简单,如果 `$input' 没有 '..' 你的测试是成功的。

【讨论】:

    【解决方案4】:

    为了回答标题中的问题,我会用 Junuxx 更新 RegExp 并允许在字符串的开头和结尾使用点:

    '/^\.?([^\.]|([^\.]\.))*$/'
    

    这是可选的.开头后跟任意数量的非.或[非.后跟.]。

    【讨论】:

      【解决方案5】:
      ^([^.]+\.?)+@$
      

      @ 之前的内容应该这样处理,剩下的留给你。 请注意,您应该对其进行更多优化以避免其他奇怪的角色设置,但这似乎足以回答您的兴趣

      别忘了^$,就像我第一次做的那样:(

      还忘了删除. - 傻我

      【讨论】:

      • 太快了!基本上回答了我的问题。谢谢。但是,有没有办法在没有正匹配的情况下形成模式。这将在 test..test@ 上返回 true,因为它将匹配最后一部分 text@
      • 是的,很抱歉,忘记了 ^ 和 $,现在应该为 test.test@ 返回 true,为 test..test@ 返回 false
      猜你喜欢
      • 1970-01-01
      • 2011-04-21
      • 2019-10-02
      • 1970-01-01
      • 2016-09-05
      • 1970-01-01
      • 2020-06-23
      • 2022-01-13
      相关资源
      最近更新 更多