在文档中我读到:

使用\A和\z来匹配字符串的开始和结束,^和$匹配一行的开始和结束。

我将应用正则表达式来检查用户提交的用户名(或电子邮件是相同的)。我应该在模型中使用validates_format_of的哪个表达式?我不明白其中的区别:我一直用^和$…


如果您依赖于正则表达式进行验证,则总是希望使用\A和\z。^和$只会匹配到换行符,这意味着他们可以使用me@example.com\n<script>dangerous_stuff();</script>这样的电子邮件,并且仍然让它有效,因为正则表达式只看到\n之前的所有内容。

我的建议是在用户名或电子邮件中完全删除新行,因为这样做几乎没有合理的理由。然后您可以安全地使用\A \z或^ $。


字符串的开始和结束不一定是一行的开始和结束。想象一下,如果你使用下面的字符串作为你的测试字符串:

我的 的名字 是 安德鲁

注意,字符串中有很多行- ^和$字符允许您匹配这些行的开头和结尾(基本上将\n字符视为delimeter),而\ a和\Z允许您匹配整个字符串的开头和结尾。


根据Pickaxe的说法:

^ 匹配一行的开头。 $ 匹配行尾。 、一个 匹配字符串的开头。 \ z 匹配字符串的结尾。 \ Z 匹配字符串的结尾,除非字符串以“\n”结尾,在这种情况下,它匹配在“\n”之前。

所以,使用\A和小写的\z。如果你使用\Z,有人可能会偷偷插入换行符。我认为这并不危险,但可能会搞砸假设字符串中没有空格的算法。根据正则表达式和字符串长度的限制,有些人可能会使用带有换行符的不可见名称。

JavaScript的Regex实现将\A视为字面的'A' (ref)。所以在比赛中注意自己并进行测试。


举例说明差异

/^foo$/匹配以下任意一个,/\Afoo\z/不匹配:

whatever1
foo
whatever2
foo
whatever2
whatever1
foo

/^foo$/和/\Afoo\z/都匹配如下:

foo