匹配单个点号但不匹配两个点号的正则表达式是什么?

8
尝试创建一个用于检查电子邮件地址的正则表达式模式。其将允许使用句点(.),但如果有多个句点相邻,则不允许。
应匹配: test.test@test.com
不应匹配: test..test@test.com
现在我知道互联网上有成千上万的电子邮件匹配示例,请不要为我发布完整解决方案的链接,我正在尝试学习。
实际上,最让我感兴趣的部分只是本地部分: test.test 应该匹配,而 test..test 不应该匹配。 谢谢您的帮助。

规范定义了如何匹配它 http://tools.ietf.org/html/rfc2822#page-17。这样构建健壮的正则表达式比仅考虑两个点的临时解决方案要容易得多。 - Esailija
实际上,我正在研究那些规范...并且遇到了第一个障碍,尝试学习正则表达式匹配一个点,但不是两个或更多挨在一起的点。 - Carbon6
1
它说本地部分可以是点原子或引用字符串,然后您查找什么是点原子,即1个原子文本,后面可以选择一个点和另一个原子文本。这自动成为一个正则表达式,使以点开头的字符串、以点结尾的字符串或在中间具有两个或多个连续点的字符串无效。为简单起见,假设原子文本只是a-z字符。那么只允许点原子的本地部分是:/^([a-z](?:\.[a-z])*)+$/ - Esailija
5个回答

6

您可以使用“管道符号|”将任意数量的[^\.](除了句点以外的任何字符)和 [^\.])\.[^\.](由两个非句点包围的句点)连接起来,并将整个内容与*(任意数量)放在^$之间,使整个字符串都由它们组成。这是代码:

$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} - challet
需要注意的是,此处不允许字符串末尾和开头出现点号。 - YakovL
而且它实际上应该是'/^([^\.]|([^\.]\.[^\.]))*$/',而不是'/^([^\.]|([^\.])\.[^\.])*$/'吗?(在[^\.]\.[^\.]周围加上括号,而不仅仅是[^\.] - YakovL
@YakovL:其实这并不重要,内部括号可以省略。括号的优先级低于析取,因此它仍然可以被正确解析。 - Junuxx

5
这对我来说更加合理:
/[^.]([\.])[^.]/

而且这很简单。向前查找和向后查找确实很有用,因为它们不会捕获值。但在这种情况下,捕获组仅围绕着中间的点。


如果字符串中有一个点,它将匹配这两个示例。 - Junuxx

1
strpos($input,'..') === false

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


0
^([^.]+\.?)+@$

至于@之前的部分,我就让你自己完成吧。 请注意,你应该进一步优化它以避免其他奇怪的字符设置,但这似乎足以回答你感兴趣的问题。

不要像我一开始那样忘记^$ :(

还忘了斜杠. - 我真是太傻了


太快了!基本上回答了我的问题。谢谢。但是,有没有一种方法可以形成一个没有正向匹配的模式。这将在test..test@上返回true,因为它将匹配最后一部分text@。 - Carbon6
抱歉,我忘记加上 ^ 和 $ 符号了,现在应该对 test.test@ 返回 true,对 test..test@ 返回 false。 - Bilal Akil

0
回答标题中的问题,我会更新Junuxx的RegExp,并允许字符串开头和结尾有点号:
'/^\.?([^\.]|([^\.]\.))*$/'

起始部分可以选择性地使用 . ,然后是任意数量的非 . 字符或[非 . 后跟 . 的字符]。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接