regex to start with a capturing group - javascript

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.

Related

regex to extract number and date from string

I'm trying to extract date, percentage or number from string. Strings can be:
the response value 10 (from here I want to extract 10)
the response value 10/12/2014 (from here I want to extract 10/12/2014)
the response value 08/2015 (from here I want to extract 08/2015)
I've written regex as (?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?) Regex is satisfying 12/12/2014, 10, 02/2012.
I'm also trying to modifying same regex to get 10, 08/2015 and 10/10/2015 but not getting how to get.
How can this be achieved?
To match your example data, you could use an alternation matching either 2 digits / 4 digits, or match 2 digits with an optional part that matches 2 digits and 4 digits.
\b(?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?)\b
Explanation
\b Word boundary, prevent the word char being part of a larger word
(?: Non capture group
\d{2}\/\d{4} Match 2 digits/4 digits
| Or
\d{2} Match 2 digits
(?:\/\d{2}\/\d{4})? Optionally match /2 digits/4 digits
) Close group
\b Word boundary
Regex demo
Note that 2 and 4 digits could also match 99 and 9999. If you want to make your match more specific, this page can be helpful https://www.regular-expressions.info/dates.html
const pattern = /\b(?:\d{2}\/\d{4}|\d{2}(?:\/\d{2}\/\d{4})?)\b/;
[
"the response value 10",
"the response value 10/12/2014",
"the response value 08/2015"
].forEach(s => console.log(s.match(pattern)[0]));
Just for fun (regex is fun) an alternative to the accepted answer:
\b(?:(?:\d\d\/){1,2}\d{4}|\d\d)\b
See the Online Demo
\b - Match a word boundary.
(?: - 1st Non-capturing group.
(?: - 2nd Non-capturing group.
\d\d\/ - Match two digits and a literal forward slash.
){1,2} - Close 2nd non-capturing group and use it once or twice.
\d{4} - Match four digits.
| - Alternation (OR).
\d\d) - Two digits and close 1st non capturing group.
\b - Match a word boundary.
Maybe we can do this even without alternation:
\b\d\d(?:(?:\/\d\d){1,2}\d\d)?\b
See the Online Demo
\b - Match a word boundary.
\d\d - Match two digits.
(?: - 1st Non-capturing group.
(?: - 2nd Non-capturing group.
\/\d\d - Match a literal slash and two digits.
){1,2} - Close 2nd non-capturing group and use it once or twice.
\d\d - Match two digits.
)? - Close 1st non-capturing group and make it optional.
\b - Match a word boundary.
Match method supports regExp and will return an array with the items you are looking for:
var date = "12/12/2014"
var arr = date.match(/(\d{2})[\/](\d{2})[\/](\d{4})/);
console.log(arr[0]);
console.log(arr[1]);
console.log(arr[2]);
console.log(arr[3]);

How do I enforce that certain characters must be present when there is an optional character before them?

I would like to capture a string that meets the criteria:
may be empty
if it is not empty it must have up to three digits (-> \d{1,3})
may be optionally followed by a uppercase letter ([A-Z]?)
may be optionally followed by a forward slash (i.e. /) (-> \/?); if it is followed by a forward slash it must have from one to three digits
(-> \d{1,3})
Here's a valid input:
35
35A
35A/44
Here's invalid input:
34/ (note the lack of a digit after '/')
I've come up with the following ^\d{0,3}[A-Z]{0,1}/?[1,3]?$ that satisfies conditions 1-3. How do I deal with 4 condition? My Regex fails at two occassions:
fails to match when there is a digit and a forward slash and a digit e.g .77A/7
matches but it shouldn't when there isa digit and a forward slash, e.g. 77/
You may use
/^(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)?$/
See the regex demo
Details
^ - start of string
(?:\d{1,3}[A-Z]?(?:\/\d{1,3})?)? - an optional non-capturing group:
\d{1,3} - one to three digits
[A-Z]? - an optional uppercase ASCII letter
(?:\/\d{1,3})? - an optional non-capturing group:
\/ - a / char
\d{1,3} - 1 to 3 digits
$ - end of string.
Visual graph (generated here):
This should work. You were matching an optional slash and then an optional digit from 1 to 3; this matches an optional combination of a slash and 1-3 of any digits. Also, your original regex could match 0 digits at the beginning; I believe that this was in error, so I fixed that.
var regex = /^(\d{1,3}[A-Z]{0,1}(\/\d{1,3})?)?$/g;
console.log("77A/7 - "+!!("77A/7").match(regex));
console.log("77/ - "+!!("77/").match(regex));
console.log("35 - "+!!("35").match(regex));
console.log("35A - "+!!("35A").match(regex));
console.log("35A/44 - "+!!("35A/44").match(regex));
console.log("35/44 - "+!!("35/44").match(regex));
console.log("34/ - "+!!("34/").match(regex));
console.log("A/3 - "+!!("A/3").match(regex));
console.log("[No string] - "+!!("").match(regex));

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

Simplify JavaScript regexp

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.

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