Luatic
Luatic

Reputation: 11201

JavaScript startsWith using regex & offset

I'm doing some string parsing and would like to use regexes. I am iterating through strings and would like to apply something like "startsWith" using a regex and an offset, returning a match if its found or null if not. In pseudo-javascript :

function startsWith(string, regex, offset) {
    if (regex_matches_at_offset) {
        return match;
    } else {
        return null;
    }
}

A simple and straightforward solution is to first apply substring and then match. But I want something like "startsWith" using a regex.

If it was a string instead of a regex, I'd go with startsWith

function startsWith(string, other_string, offset) {
    let starts_with=s.startsWith(other_string, offset); // startsWith from position offset onwards, as other_string has fixed length the "match" is also known
    if (starts_with) {
        return other_string; // other_string = match
    } else {
        return null;
    }
}

But for regexes, my current solution (for testing purposes only) looks like :

function startsWith(string, regex, offset) {
    let end_part=s.substring(offset); // Substring, performance issue
    let match=end_part.match(regex); // Match it as we need the match
    if (match.length === 0) {
        return null;
    } else {
        match=match[0]; // Only care about 1st match
    }
    if (end_part.startsWith(match)) { // Check if match already starts at first position
        return match;
    } else {
        return null;
    }
}

Which is not very satisfying as there are obvious problems (copying most of the string, performing the regex search twice...

Expected :

  1. Find regex in string starting from given position, not only boolean but also match
  2. High performance (do not copy entire string, for example)

Examples :

startsWith("Hello world !", /h/i, 0); // "H"
startsWith("Hello world !", /wor?/i, 6); // "wor"
startsWith("Hello world !", /wor?/i, 10); // null
startsWith("Hello world !", /z/i, 0); // null

Upvotes: 1

Views: 3109

Answers (1)

Code Maniac
Code Maniac

Reputation: 37775

One way is to build an regex based on offset and pattern passed as string

  • Here initial part of regex uses . to match any character upto offset
  • Second use passed pattern in captured group to return only desired match

let startsWith = (str, reg, offset) =>{
  let regex = `^.{${0,offset}}(${reg})`
  let final = new RegExp(regex,'i')
  let found = str.match(final)
  console.log(found ? found[1] : found)
}

startsWith("Hello world !", 'h', 0); // "H"
startsWith("Hello world !", 'wor?', 6); // "wor"
startsWith("Hello world !", 'wor?', 10); // null
startsWith("Hello world !", 'z', 0); // null

As mentioned by @mark we can use source property to if we want regex to be passed as argument to function

let startsWith = (str, reg, offset) =>{
  let regex = `^.{${0,offset}}(${reg.source})`
  let final = new RegExp(regex,'i')
  let found = str.match(final)
  console.log(found ? found[1] : found)
}

startsWith("Hello world !", /h/i, 0); // "H"
startsWith("Hello world !", /wor?/i, 6); // "wor"
startsWith("Hello world !", /wor?/i, 10); // null
startsWith("Hello world !", /z/i, 0); // null

Upvotes: 6

Related Questions