14

I have the following route:

  get 'users/:user_id/:name', to: 'profiles#show',
    :constraints => { :name => /[a-zA-Z0-9_]+$/ }, as: 'user_profile'

Which produces the error:

Regexp anchor characters are not allowed in routing requirements: /[a-zA-Z0-9_]+$/

So I get that the ^ character isn't allowed, but not sure what character is producing this particular routing error.

Toto
  • 83,193
  • 59
  • 77
  • 109
keruilin
  • 14,638
  • 30
  • 103
  • 172

2 Answers2

17

The regex anchors are ^ and $, but they don't achieve anything here. "(Y)ou don’t need to use anchors because all routes are anchored at the start.".

So the constraint:

:constraints => { :name => /[a-zA-Z0-9_]+/ }

will do what you want - ensure the name is composed of 1 or more of those characters, and nothing else. BTW you can simplify the regex:

:constraints => { :name => /\w+/ }
mahemoff
  • 38,430
  • 30
  • 133
  • 196
  • 2
    in rails 2 use. , :requirements => {:id => /[A-Z0-9]{1,}([\/_-]{1}[A-Z0-9]{1,})*/i} – Navin Jul 03 '18 at 11:16
  • "...anchored to the start." But not the end? I don't see how this removes the need for the `$` end anchor. – Dogweather Jun 23 '20 at 09:23
  • The linked guide indeed only mentions the start. You may be right that the `$` is still valid. I was assuming not because the error says "anchor characters", but the pluraility may be due to other characters such as \A. Would need to be checked. – mahemoff Jul 07 '20 at 06:49
13

In regex we have two anchors:

  1. Beginning of line/string ^
  2. End of line/string $

Try to remove $ from the pattern and you should be good to go...

Ωmega
  • 37,727
  • 29
  • 115
  • 183
  • 6
    There are also `\A` and `\Z` of those I know of. – rausch Apr 16 '13 at 15:15
  • 1
    @rausch - Generally speaking, in regular expressions you better keep using the caret and dollar for this purpose. Some environments (JavaScript, POSIX, XML) do not support `\A` and `\Z`. – Ωmega Apr 17 '13 at 01:14
  • @Ωmega In Ruby you shouldn't do that; always reaching for `^` and `$` could lead to security vulnerabilities: http://homakov.blogspot.ru/2012/05/saferweb-injects-in-various-ruby.html http://guides.rubyonrails.org/security.html#regular-expressions – Abe Voelker Oct 06 '16 at 19:42
  • Actually `\z` (lowercase "z") matches exactly end-of-string. Using `\Z` (uppercase) will match EOS **or** immediately-before-a-final-newline. E.g. this succeeds: `"abc\n".match(/c\Z/)` – Kelvin Feb 07 '19 at 19:58
  • @Kelvin - Right, but not all engines support `\z` – Ωmega Feb 07 '19 at 22:19
  • 1
    @Ωmega yeah I understand. I was actually replying to rausch's comment. In any case, the question is about ruby, and I believe it's best to use the constructs particular to ruby that do what is intended. This is just one of the differences to be aware of when porting to another language/engine. – Kelvin Feb 08 '19 at 19:52