2

I am trying to write a function which will parse a string in the form of 7:55am - 9:10am (TR) 8:10am - 9:00am (W) and output a multi dimensional ]array containing the regex result (ex [[7:55am, 9:10am, TR], [7:55am, 9:00am, W]])

This is my function as it currently stands:

function parseClassTime(times) {
    console.log("Input: " + times);
    var timeArr = [];
    var finalArr = [];
    regexStr = /(\d{1,2}:\d{2}[ap]m) - (\d{1,2}:\d{2}[ap]m) \((\w{1,5})\)/g;
    if (times.indexOf(") ") > -1) {
        times = times.replace(") ", ")&");
        timeArr = times.split("&");
    } else {
        timeArr.push(times);
    }
    console.log("timeArr: " + timeArr);
    for (i = 0; i < timeArr.length; i++) {
        console.log(i + ":" + timeArr[i]);
        console.log("regexResult: " + regexStr.exec(timeArr[i]));
    }
};

And this is the output that I am getting:

Input: 7:55am - 9:10am (TR) 8:10am - 9:00am (W)
timeArr: 7:55am - 9:10am (TR),8:10am - 9:00am (W)
0:7:55am - 9:10am (TR)
regexResult: 7:55am - 9:10am (TR),7:55am,9:10am,TR
1:8:10am - 9:00am (W)
regexResult: null

For the life of me I cannot discover where that null is coming from. Does something happen to the regex string between the two calls to .exec()?

Please let me know your thoughts!

8
  • Just change {0,5} to {1,5}. I think it's matching for zero length too. Commented Apr 5, 2016 at 20:54
  • First, you have am and pm dangling, use [ap]m, then - as the comment above states - {0,5} can match 0 characters. Try (\d{1,2}:\d{2}[ap]m) - (\d{1,2}:\d{2}[ap]m) \((\w+)\). Commented Apr 5, 2016 at 20:54
  • Thanks for the suggestions guys! I changed it however I am still getting a null value Commented Apr 5, 2016 at 20:58
  • 1
    There is an issue with the code. Commented Apr 5, 2016 at 20:59
  • Should the loop's upper limit be array.length-1 ? Commented Apr 5, 2016 at 21:00

1 Answer 1

1

It is just how [RegExp.exec()][1] works: the lastIndex property got set to 20 after the first match and you did not reset it. The second time, it could not match anything as it started looking for a match at Position 20. This all happens this way because the regex is built with the global modifier /g.

If your regular expression uses the "g" flag, you can use the exec() method multiple times to find successive matches in the same string. When you do so, the search starts at the substring of str specified by the regular expression's lastIndex property

You can reset the regexStr.lastIndex manually:

function parseClassTime(times) {
    console.log("Input: " + times);
    var timeArr = [];
    var finalArr = [];
    regexStr = /(\d{1,2}:\d{2}[ap]m) - (\d{1,2}:\d{2}[ap]m) \((\w{1,5})\)/g;
    if (times.indexOf(") ") > -1) {
        times = times.replace(") ", ")&");
        timeArr = times.split("&");
    } else {
        timeArr.push(times);
    }
    console.log("timeArr: " + timeArr);
    for (i = 0; i < timeArr.length; i++) {
        regexStr.lastIndex = 0;              // <= HERE!!
        console.log(i + ":" + timeArr[i]);
        console.log("regexResult: " + regexStr.exec(timeArr[i]));
    }
};

parseClassTime("7:55am - 9:10am (TR) 8:10am - 9:00am (W)");

Or a shorter way:

var finalArr = [];
var regexStr = /(\d{1,2}:\d{2}[ap]m) - (\d{1,2}:\d{2}[ap]m) \((\w+)\)/g;
var times = "7:55am - 9:10am (TR) 8:10am - 9:00am (W)";
while ((m=regexStr.exec(times)) !== null) {
	finalArr.push([m[1], m[2], m[3]]);
}
console.log(finalArr);

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.