Ruby 正则表达式中 \A \z 和 ^ $ 之间的区别

Posted

技术标签:

【中文标题】Ruby 正则表达式中 \\A \\z 和 ^ $ 之间的区别【英文标题】:Difference between \A \z and ^ $ in Ruby regular expressionsRuby 正则表达式中 \A \z 和 ^ $ 之间的区别 【发布时间】:2010-10-09 07:47:18 【问题描述】:

在我阅读的文档中:

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

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

【问题讨论】:

guides.rubyonrails.org/security.html#regular-expressions 【参考方案1】:

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

我的建议是预先从用户名或电子邮件中完全删除新行,因为几乎没有正当理由。然后你可以安全地使用\A\z^$

【讨论】:

@Ragmaanir 是对的,应该是小写字母\z 而不是\Z +1 谢谢!尽管我不得不不同意您的建议:A)如果有适当的包罗万象,请不要添加不必要的工作/处理,并且 B)尤其是如果它允许您懒惰地区分两者,则不要添加。您可能并不总是能够对字符串进行操作,只能对正则表达式进行操作,因此请记住正确的字符串并知道其中的区别! 我不理解带有危险内容的示例,因为在任何一种情况下,字符串中都可能包含危险内容,无论是否有新行,这都是一个漏洞,应该通过 html 清理和验证来修复. @JayrMotta 演示表明危险的东西会完全绕过你的整个正则表达式检查。因此,即使您正在检查正则表达式中的危险内容,如果您使用 $ 而不是 \z 来检查“字符串结尾”,它也会被绕过。【参考方案2】:

根据Pickaxe:

^ 匹配行首。

$ 匹配行尾。

\A 匹配字符串的开头。

\z 匹配字符串的结尾。

\Z 匹配字符串的结尾,除非字符串以"\n" 结尾,在这种情况下,它匹配"\n" 之前的位置。

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

javascript 的 Regex 实现将 \A 视为文字 'A' (ref)。所以请注意自己并进行测试。

【讨论】:

【参考方案3】:

字符串的开头和结尾不一定与行的开头和结尾相同。想象一下,如果您使用以下内容作为测试字符串:

我的 名称 是 安德鲁

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

【讨论】:

【参考方案4】:

示例差异

    /^foo$/ 匹配以下任何一项,/\Afoo\z/ 不匹配:
whatever1
foo
whatever2
foo
whatever2
whatever1
foo
    /^foo$//\Afoo\z/ 都匹配以下内容:
foo

【讨论】:

以上是关于Ruby 正则表达式中 \A \z 和 ^ $ 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

Python之正则表达式模块

Ruby 用捕获的正则表达式模式替换字符串

正则表达式——7.4 单词边界

Puppet正则表达式(十七)

ruby 正则表达式

ruby 正则表达式Regexp