Разница между \ A \ z и ^ $ в регулярных выражениях Ruby

137

В документации я читал:

Используйте\A и \z для соответствия началу и концу строки, ^ и $соответствуют началу/концу строки.

Я собираюсь применить регулярное выражение для проверки имени пользователя (или электронной почты - то же самое), представленного пользователем. Какое выражение следует использовать с validates_format_of в модели? Я не могу понять разницу: я всегда использовал ^ и $...

Теги:

4 ответа

169
Лучший ответ

Если вы зависите от регулярного выражения для проверки, вы всегда хотите использовать \A и \z. ^ и $ будут соответствовать только символу новой строки, что означает, что они могут использовать электронную почту, например [email protected]\n<script>dangerous_stuff();</script>, и все еще имеют ее проверку, так как регулярное выражение только видит все до \n.

Моя рекомендация будет просто полностью удалять новые строки из имени пользователя или электронной почты заранее, так как практически нет законных оснований для одного. Затем вы можете безопасно использовать EITHER \A \z или ^ $.

  • 12
    @Ragmaanir прав, он должен быть с маленькой буквой \z вместо \Z !
  • 7
    +1 Спасибо! Хотя я бы не согласился с вашей рекомендацией: A) Не добавляйте ненужную работу / обработку, если есть подходящее универсальное средство, и B), особенно если это не позволяет вам лениться в различении между ними. Возможно, вы не всегда в состоянии манипулировать строками, только в Regex, так что оставьте правильный в памяти и почувствуйте разницу!
Показать ещё 2 комментария
136

Согласно Pickaxe:

^    Соответствует началу строки.

$    Соответствует концу строки.

\A    Соответствует началу строки.

\z    Соответствует концу строки.

\z    Соответствует концу строки, если строка не заканчивается на "\n", и в этом случае она соответствует непосредственно перед "\n".

Итак, используйте \A и нижний регистр \z. Если вы используете \z, кто-то может прокрасться в символ новой строки. Это не опасно, я думаю, но может испортить алгоритмы, которые предполагают, что в строке нет пробелов. В зависимости от ограничений регулярного выражения и длины строки кто-то может использовать невидимое имя только с символом новой строки.

JavaScript-реализация Regex рассматривает \A как литерал 'A' (ref). Поэтому следите за собой и проверяйте.

  • 14
    +1 за ссылку на какой-либо справочный материал (даже если вы опоздали на пару лет :)
  • 1
    Больше голосов, чем сам ответ. ПОЗИЦИЯ ВЫИГРЫВАЕТ!
8

Начало и конец строки могут не совпадать с началом и концом строки. Представьте, что в качестве тестовой строки вы использовали следующее:

мой
имя
это
Эндрю

Обратите внимание, что строка содержит много строк - символы ^ и $ позволяют вам сопоставлять начало и конец этих строк (в основном обрабатывая символ \n как разделитель), а \A и \Z позволяет вам сопоставлять начало и конец всей строки.

  • 0
    Лучший ответ на мой взгляд. «В основном, трактовка символа \ n как разделителя» действительно помогла мне понять, спасибо.
4

Разница по примеру

  • /^foo$/ соответствует любому из следующих элементов, /\Afoo\z/:
whatever1
foo
whatever2
foo
whatever2
whatever1
foo
  1. /^foo$/ и /\Afoo\z/ соответствуют следующему:
foo

Ещё вопросы

Сообщество Overcoder
Наверх
Меню