Search code examples
javascriptparsinginfinite-loop

Infinite loop in JS when parsing between digits


I'm trying to split a list into sublists of whenever there are digits or not, without losing any data like I would with split(). This is pretty embarassing, but I'm running into an infinite loop, and I can't figure out the bug for the life of me. Thanks for the help!

const parseArg = arg => {
  const parsedList = [];
  let pos, str;
  let grabbingDigits = false;
  while (arg.length != 0) {
    pos = grabbingDigits ? arg.search(/\d/) : pos = arg.search(/^\d/);
    str = arg.substring(0,pos);
    arg = pos != -1 ? arg.substring(pos) : arg;
    parsedList.push(str);
    grabbingDigits = !grabbingDigits;
  }
  return parsedList;
}
console.log(parseArg('abc123def')); //=> should be ['abc','123','def']

Solution

  • It would probably be easier to use just a single global regular expression: match digits with \d+, or match non-digits with \D+:

    const parseArg = arg => arg.match(/\d+|\D+/g);
    console.log(parseArg('abc123def')); //=> should be ['abc','123','def']

    For a more programmatic approach like your original code, inside the loop, identify the number of characters from the (current) start of arg that are digits or non-digits, then .slice appropriately:

    const parseArg = arg => {
      const parsedList = [];
      while (arg.length != 0) {
        const thisLength = arg.match(/^\d/)
          ? arg.match(/^\d+/)[0].length
          : arg.match(/^\D+/)[0].length;
        parsedList.push(arg.slice(0, thisLength));
        arg = arg.slice(thisLength);
      }
      return parsedList;
    }
    console.log(parseArg('abc123def')); //=> should be ['abc','123','def']