0

I have this regular expression :

new RegExp("[a-zA-Z]{1}[/]{1}" + userName + "[/]{1}[a-zA-Z0-9-_]+$", "i")

This provides me much of my required results. However I am unable to check one condition:

I do not want my last character to be '-'. It could be present anywhere after second '/', just not the last character. More precisely last character should be anything [a-zA-Z0-9_] but not a hyphen '-'.

I checked out this, but could not wrap my head around it. How is this done exactly.

Community
  • 1
  • 1
Saurabh Tiwari
  • 4,632
  • 9
  • 42
  • 82
  • This question is only related to JavaScript, I removed Perl tag. – Wiktor Stribiżew May 10 '17 at 12:24
  • However, that solution does not let you have 1 char in the last part of the string. It is just incorrect. `[^-]` is a character class that is a consuming pattern. Only a zero-width assertion solution is correct: based on anchors, word boundaries or lookarounds (lookahead/lookbehind). – Wiktor Stribiżew May 10 '17 at 12:59

5 Answers5

2

Improving your regex [/]{1}[a-zA-Z0-9-_]+$.

  1. You don't need [/]{1}, you can simply use / (except in a literal regex object that is delimited by slashes, in this case you need to escape it \/)

  2. - within character class should be places either at beginning or at end to avoid matching ASCII ranges. You used [a-zA-Z0-9-_]. Instead you could just use [\w-]. \w is shorthand for character class [a-zA-Z0-9_].

It could be present anywhere after second '/', just not the last character.

Just make the last character non-hyphen using [^-] at end.

Regex:

new RegExp("[a-zA-Z]/" + userName + "/[\w-]+[^-]$", "i")

OR

new RegExp("[a-zA-Z]/" + userName + "/[\w-]+\w$", "i") if the last character is strictly within the \w character class.

Regex101 Demo 1

Regex101 Demo 2

Rahul
  • 2,658
  • 12
  • 28
1

In your particular case, you may add a word boundary before $ since all other chars you match are word chars:

new RegExp("[a-zA-Z]/" + userName + "/[a-zA-Z0-9-_]+\\b$", "i")
                                                    ^^^^

See the regex demo

Else, use a negative lookahead, which is a more universal solution that will work regardless of what chars you match here:

new RegExp("[a-zA-Z]/" + userName + "/(?!.*-$)[a-zA-Z0-9-_]+$", "i")
                                      ^^^^^^^^ 

See another regex demo.

Some notes:

  • / needs no escaping when you use it inside a constructor notation
  • {1} is always redundant as each atom is matched once by default
  • \\b needs double escaping because a word boundary is a combination of a literal \ and the letter b, and if you use "\b", it will match a backspace char
  • NOTE: if userName contains special regex chars, you'd better consider escaping the variable contents to be parsed as literal chars.
Community
  • 1
  • 1
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
1

Is this what you are looking for?

new RegExp("[a-zA-Z]{1}[/]{1}" + userName + "[/]{1}[a-zA-Z0-9-_]+[a-zA-Z0-9_]$", "i")
amiramw
  • 506
  • 2
  • 10
0

in case last character should not match -, the last - has to be removed from last character set :

new RegExp("[a-zA-Z]{1}[/]{1}" + userName + "[/]{1}[a-zA-Z0-9-_]+$", "i")

to be changed to

new RegExp("[a-zA-Z]{1}[/]{1}" + userName + "[/]{1}[a-zA-Z0-9-_]+[a-zA-Z0-9_]$", "i")

also {1} are useless because it's implicit

new RegExp("[a-zA-Z][/]" + userName + "[/][a-zA-Z0-9-_]+[a-zA-Z0-9_]$", "i")
Nahuel Fouilleul
  • 18,726
  • 2
  • 31
  • 36
0

Or simply

new RegExp("^[a-z]/" + userName + "/[\w-]*\w$", "i")

I.e. your character class [a-zA-Z0-9-_] is the same as shorthand class \w - word character, plus hyphen - [\w-]. And ending the match with \w will do what you want - not allowing a hyphen at the end.

In the first regex A-Z is unnecessary because the whole thing is case insensitive thanks to the "i" flag.

SamWhan
  • 8,296
  • 1
  • 18
  • 45