admataz
10/17/2018 - 10:05 PM

async regex iterator

Uses Generator function to compose an iterator that can do stuff with each match before moving on to the next one.

/**
 * Generator function to produce an iterable result of regex matches that can be
 * asyncronously processed and converted
 */
function* findMatchesIterator(matcher, stringToSearch) {
  let result
  let matchFound
  while (matchFound !== null) {
    matchFound = result = matcher.exec(stringToSearch)
    if (matchFound) {
      yield result
    }
  }
}

/**
 * Compose an async replacer function for a specific match
 */
 export const matchesReplacer = (tokenPattern, matchProcesser) => async (
  stringToReplace
) => {
  const matches = []
  const i = findMatchesIterator(tokenPattern, stringToReplace)
  let currentMatch = i.next()
  while (!currentMatch.done) {
    try {
      const matchToReplace = await matchProcesser(currentMatch.value)
      if (matchToReplace) {
        matches.push(matchToReplace)
      }
    } catch (err) {
      logger.error(`Error matching ${tokenPattern} - ${err}`)
      return ''
    }
    currentMatch = i.next()
  }
  let newString = stringToReplace
  matches.forEach(r => {
    newString = newString.replace(r.matchedString, r.replaceWith)
  })
  return newString
}