Simplify JavaScript regexp - javascript

How can I simplify my regexp (^(\w+)\/(\w+)\/(\d+)$|^(\w+)\/(\w+)\/$|^(\w+)\/(\w+)$) to match examples like controller/action(/id)? My current regex looks so long and complex :(
Matching examples:
controller/action
controller/action/
controller/action/123
Non-matching:
controller/
controller/action/action
controller/action/123/
controller/action/123/456

You can use the following regex featuring optional groups:
^(\w+)\/(\w+)(?:\/(\d+)?)?$
^^^ ^ ^
See the regex demo
This regex matches:
^ - start of a string
(\w+) - one or more alphanumeric or underscore characters
\/ - a / symbol
(\w+) - one or more alphanumeric or underscore characters
(?:\/(\d+)?)? - an optional (one or zero occurrences) sequence (due to (?:...)? construct, a non-capturing group (?:...) + a ? - one or zero - quantifier) matching
\/ - a forward slash
(\d+)? - optional capturing group matching one or more digits (but this group can be missing since the ? quantifier is applied to the whole group (...))
$ - end of string anchor.

Related

regex for simple arithmetic expression

I've read other stackoverflow posts about a simple arithmetic expression regex, but none of them is working with my issue:
I need to validate this kind of expression: "12+5.6-3.51-1.06",
I tried
const mathre = /(\d+(.)?\d*)([+-])?(\d+(.)?\d*)*/;
console.log("12+5.6-3.51-1.06".match(mathre));
but the result is '12+5', and I can't figure why ?
You only get 12.5 as a match, as there is not /g global flag, but if you would enable the global flag it will give partial matches as there are no anchors ^ and $ in the pattern validating the whole string.
The [+-] is only matched once, which should be repeated to match it multiple times.
Currently the pattern will match 1+2+3 but it will also match 1a1+2b2 as the dot is not escaped and can match any character (use \. to match it literally).
For starting with digits and optional decimal parts and repeating 1 or more times a + or -:
^\d+(?:\.\d+)?(?:[-+]\d+(?:\.\d+)?)+$
Regex demo
If the values can start with optional plus and minus and can also be decimals without leading digits:
^[+-]?\d*\.?\d+(?:[-+][+-]?\d*\.?\d+)+$
^ Start of string
[+-]? Optional + or -
\d*\.\d+ Match *+ digits with optional . and 1+ digits
(?: Non capture group
[-+] Match a + or -
[+-]?\d*\.\d+ Match an optional + or - 0+ digits and optional . and 1+ digits
)+ Close the noncapture group and repeat 1+ times to match at least a single + or -
$ End of string
Regex demo
You would try to use this solution for PCRE compatible RegExp engine:
^(?:(-?\d+(?:[\.,]{1}\d)?)[+-]?)*(?1)$
^ Start of String
(?: Non capture group ng1
(-?\d+(?:[\.,]{1}\d)?) Pattern for digit with or without start
"-" and with "." or "," in the middle, matches 1 or 1.1 or 1,1
(Matching group 1)
[+-]? Pattern for "+" or "-"
)* Says
that group ng1 might to repeat 0 or more times
(?1) Says that
it must be a digit in the end of pattern by reference to the first subpattern
$ End of string
As JS does not support recursive reference, you may use full version instead:
/^(?:(-?\d+(?:[\.,]{1}\d)?)[+-]?)*(-?\d+(?:[\.,]{1}\d)?)$/gm

Regex to validate hypen(-) at start and end of the string

I'm validating a string("-test-") whether it contains hypens(-) at start and end of the string using regex. So i found an regex to restrict hypen at start and end of regex.
/^(?!-)[a-zA-Z0-9-' ]+[^-]$/i
This regex was validating as expected when the string contains more than one char("aa") with or without hypen. But its not working as expected when i'm simply passing one character string("a") without hypen.
And also these need to allow special characters and alphanumeric characters like "$abcd&". Need to restirct oly hypen at start and end of the string.
Could you guys help out of this..
The pattern you have matches a string that consists of at least 2 chars because [a-zA-Z0-9-' ]+ needs 1 char to match and [^-] requires another char to be present.
You may revamp the lookahead to also fail a string that ends with -:
/^(?!-)(?!.*-$).+$/
^^^^^^^^
See the regex demo
Details
^ - start of a string
(?!-)(?!.*-$) - negative lookaheads that fail the match if the string starts with - or ends with -
.+ - any 1 or more chars other than line break chars (use [\s\S] to match any char)
$ - end of string.
An unrolled version for this pattern would be
^[^-]+(?:-+[^-]+)*$
See this regex demo
Details
^ - start of string
[^-]+ - 1 or more chars other than -
(?:-+[^-]+)* - 0+ sequences of
-+ - 1+ hyphens
[^-]+ - 1 or more chars other than -
$ - end of string.
To allow any character but only disallow hyphen at start and end:
^(?!-).*[^-]$
^ start of string
(?!-) look ahead if there is no hyphen
.* match any amount of any character
[^-] match one character, that is not a hyphen
$ at the end
See demo at regex101

How do I allow only a comma to be last character

I have this:
ng-pattern="/^[a-zA-Z0-9]+(?:[,\/-](?:\s)*[a-zA-Z0-9]*)*$/"
This matches even fada/, fada-. I need it to match only if it's fada, and for / and - there has to be something that follows it.
regexr.com/3u1d0
You may use
^[a-zA-Z0-9]+(?:[,\/-]~\s*[a-zA-Z0-9]+)*,?$
See the pattern demo
Details
^ - start of string
[a-zA-Z0-9]+ - 1+ ASCII alphanumeric chars
(?:[,\/-]\s*[a-zA-Z0-9]+)* - zero or more consecutive sequences of:
[,\/-] - a ,, / or -
\s* - 0+ whitespaces
[a-zA-Z0-9]+ - 1+ ASCII alphanumeric chars
,? - an optional (one or zero) comma
$ - end of string.
You can use | to separate the pattern for , from [\/-] instead:
/^[a-zA-Z0-9]+(?:,$|(?:[\/-]\s*[a-zA-Z0-9]+)*$)/

regex to start with a capturing group

I have this regEx to match the following patterns:
/(((fall|spring|summer)\s\d{4});|(waived)|(sub\s[a-zA-Z]\d{3}))/ig
Should match:
fall 2000;
spring 2019; waived
summer 1982; sub T676
Should not match ANY string that does not start with the first capturing group ((fall|spring|summer)\s\d{4}) such as:
waived Fall 2014;
sub Fall 2011; waived
To make sure that each matching pattern starts with this group ((fall|spring|summer)\s\d{4})
I tried appending ^ in front of the first group like this, /(^((fall|spring|summer)\s\d{4});|(waived)|(sub\s[a-zA-Z]\d{3}))/ig, but the results were inconsistent.
Demo
You may use
/^(fall|spring|summer)\s\d{4};(?:.*(waived|sub\s[a-zA-Z]\d{3}))?/i
See the regex demo.
Details
^ - start of string
(fall|spring|summer) - one of the three alternatives
\s - a whitespace
\d{4} - 4 digits
; - a semi-colon
(?:.*(waived|sub\s[a-zA-Z]\d{3}))? - an optional sequence of:
.* - any 0+ chars other than line break chars, as many as possible (if the values you need are closer to the start of string, replace with a lazy .*? counterpart)
( - start of a grouping construct
waived - a waived substring
| - or
sub - a sub substring
\s - a substring
[a-zA-Z] - an ASCII letter
\d{3} - three digits
) - end of the grouping construct.

Regex - Not containing a string and not ending with a /

How do I create a regular expression which don't contain the string "umbraco" and doesn't end with a /
This is the what I have so far but I'm unable to get it fully working, any help would be appreciated.
(?!umbraco)(?![/]$)
Test strings would be:
http://www.domain.com/umbraco/login.aspx - shouldn't match
http://www.domain.com/pages/1/ - shouldn't match
http://www.domain.com/pages/1 - should match
It should be this regex:
^(?!.*?umbraco).*?[^\/]$
Online Demo: http://regex101.com/r/lM0cS9
Explanation:
^ assert position at start of a line
(?!.*?umbraco) Negative Lookahead - Assert that it is impossible to match the regex below
.*? matches any character (except newline)
Quantifier: Between zero and unlimited times, as few times as possible, expanding as needed
umbraco matches the characters umbraco literally (case sensitive)
.*? matches any character (except newline)
Quantifier: Between zero and unlimited times, as few times as possible, expanding as needed
[^\/] match a single character not present in the list below
\/ matches the character / literally
$ assert position at end of a line
This should be the regex
^(?!.*?umbraco).*?[^\/\s*\n*]$
demo http://rubular.com/r/tEhY7JFjXK

Categories