2

I am writing a mod rewrite rule to allow only one period between an arbitrary length characters. The characters must begin with a letter, followed by 2-29 characters or numbers, and allow only one period (optional) somewhere in the middle (but never in the end).

Here is what I have so far:

RewriteCond    %{REQUEST_FILENAME}        !-f
RewriteCond    %{REQUEST_FILENAME}        !-d
RewriteRule    ^([a-z]([.a-z0-9]{2,29}))$    user.php?u=$1     [NC,QSA,L]

This rule is not working since it allows things like f.oo (valid), foo. (invalid), f.o.o (invalid), or even f.......

Is it possible to accomplish using just apache's mod rewrite? Or does the check have to be done in PHP or somewhere else?

Similar questions: this one and this one.

Thank you.

Community
  • 1
  • 1
Sutandiono
  • 1,748
  • 1
  • 12
  • 21
  • http://stackoverflow.com/questions/2674574/rewriterule-being-greedy – L0j1k Dec 24 '12 at 08:02
  • @L0j1k I'm confused. If I'm following the answer by Jon Lin, did you mean I need to put 29 rewrite rules for every possible position of the period in the middle? – Sutandiono Dec 24 '12 at 08:14

2 Answers2

1

I can't figure out how to do it in one regex, but you could stack your regex's

^[a-z][.a-z0-9]{2,29}$     #3-30 characters long, starting with a letter, then nums
^[a-z0-9]+\.?[a-z0-9]+$    #has zero or one dot in middle

updated to take numbers into account

http://regex101.com/r/nD2lI6

http://regex101.com/r/gR3vA1

So the full example should be something like:

RewriteCond    %{REQUEST_FILENAME}        !-f
RewriteCond    %{REQUEST_FILENAME}        !-d
RewriteCond    %{REQUEST_URI}  ^[a-z][.a-z0-9]{2,29}$
RewriteRule    ^([a-z0-9]+\.?[a-z0-9]+)$     user.php?u=$1     [NC,QSA,L]
Amir T
  • 2,708
  • 18
  • 21
  • Two regexes are fine, but we still need to account for the numbers that can appear starting from character #2. And btw, did you mean to have the two regexes above as part of `RewriteCond` and keep my `RewriteRule` as above? – Sutandiono Dec 24 '12 at 08:32
  • right - updated to take numbers into account and listed the full example – Amir T Dec 24 '12 at 08:43
  • strange, works for me - I updated the regex links to match the updated patterns. anyway seems like you got it working. – Amir T Dec 24 '12 at 22:00
  • Individually, both rules work as intended. However, when combined, they don't seem to add up to the rule we're looking for. Not sure where it went wrong, though. But thank you for the help. – Sutandiono Dec 25 '12 at 10:56
1

I couldn't do it in one rule, so I used two:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 ^.{3,30}$
RewriteRule ^([a-z][a-z0-9]*(?:\.[a-z0-9]+)?)$ user.php?u=$1 [NC,QSA,L]
Salman A
  • 262,204
  • 82
  • 430
  • 521
  • 1
    `?:` means the parenthesis is a non-capturing group. If absent, the `.` and everything after it would be captured in `$2`. `?:` is added to explicitly state that we are not interested in `$2`. – Salman A Dec 24 '12 at 09:43