One way to work around JS's lack of lookbehind is to use non-capturing (?: )
and capturing groups ()
. Non-capturing groups are matched but not 'remembered', and capturing groups are stored.
As it is with regex, the following is a little dense, but you can see there are three sets of parentheses - a non-capturing, a capturing, and then a non-capturing:
let regexString = /(?:[A-Z]{4}[\d]{3}\s)([A-za-z0-9 ]+)(?:\s\d)/g
The first non-captured group (?:[A-Z]{4}[\d]{3}\s)
matches but doesn't remember the course alphanumeric code. The second ([A-za-z0-9 ]+)
matches and captures any list of A-Za-z0-9
characters at least once +
in the ()
– i.e. the title. The last tells it to stop matching for the space+'3' with (?:\s\d)
.
The second issue with capturing groups and javascript is that they are only returned when you use regexString.exec()
, and not when you use .match()
. .exec()
returns an array, with the matched text as the zeroth (not what is wanted here as it includes the non-capturing groups), and then the subsequent indices are capturing groups.
let match1 = x.exec('AAFS209 American Music 3')[1]
= 'American Music'
.
let match2 = x.exec('AAFS241 3D American Musical Theatre 3')[1]
= '3D American Musical Theatre'
. (Not sure if that is a course, let alone a thing, but one can hope. Also, wanted to make the regex worked with digits in the title).