JavaScript使用正则表达式和偏移量开始

时间:2019-05-27 16:44:55

标签: javascript regex string performance regex-group

我正在做一些字符串解析,并且想使用正则表达式。我正在遍历字符串,并想使用正则表达式和偏移量来应用“ startsWith”之类的东西,如果找到则返回匹配,否则返回null。在伪JavaScript中:

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

一个简单直接的解决方案是首先应用子字符串,然后进行匹配。但是我想要使用正则表达式之类的“ startsWith”之类的东西。

如果它是字符串而不是正则表达式,那么我会选择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;
    }
}

但是对于正则表达式,我当前的解决方案(仅用于测试目的)如下所示:

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;
    }
}

这不是很令人满意,因为存在明显的问题(复制大多数字符串,两次执行正则表达式搜索...

预期:

  1. 从给定位置开始查找字符串中的正则表达式,不仅布尔值而且匹配
  2. 高性能(例如,请勿复制整个字符串)

示例:

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

1 个答案:

答案 0 :(得分:4)

一种方法是基于偏移量和作为字符串传递的模式来构建正则表达式

  • 此处regex的初始部分使用.来匹配任何字符,直到offset为止。
  • 第二次在捕获的组中使用传递的模式仅返回所需的匹配项

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

@mark所述,如果希望将正则表达式作为函数的参数传递,则可以使用source属性

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