在字符串中查找最多只有一个不同字符的子字符串-javascript

时间:2017-02-05 21:31:42

标签: javascript regex

我是编程新手,现在我正在开发一个程序。程序需要在字符串中查找子字符串并返回链开始相同的索引。我知道为此我可以使用" indexOf"。不是那么容易。我想在moste找到一个不同的字符串。 我正在考虑定期表达...但不知道如何使用它因为我需要对字符串的每个元素使用常规表达式。这里有一些代码可以说明我想要做的事情:

var A= "abbab"; 
var B= "ba";
var tb=[];

console.log(A.indexOf(B));

  for (var i=0;i<B.length; i++){
    var D=B.replace(B[i],"[a-z]");
    tb.push(A.indexOf(D));        
  }
console.log(tb);

我知道子串B和字符串A是小写字母。如果使用常规表达式获取任何建议,将会很高兴。 THX

Simple Input:
A B
1) abbab ba
2) hello world
3) banana nan
Expected Output:
1) 1 2
2) No Match!
3) 0 2

1 个答案:

答案 0 :(得分:0)

虽然理论上可能是可能的,但我认为在尝试将所有可能的搜索查询选项合并到一个长复杂的正则表达式中时尝试这种搜索会非常复杂。我认为更好的方法是使用JavaScript动态创建各种更简单的选项,然后分别搜索每个选项。

以下代码使用正则表达式通配符(即句点'。')依次替换初始查询字符串中的每个字符,然后使用该字符串搜索目标字符串。例如,如果初始查询字符串为“nan”,则将使用“.an”,“n.n”和“na。”进行搜索。如果该位置尚未在先前的搜索中被击中,则它仅将命中的位置添加到命中列表中。即它确保命中列表仅包含唯一值,即使多个查询变体在同一位置发现命中。 (这可以通过ES6集更好地实现,但是在尝试使用集合时我无法使用Stack Overflow代码片段工具与我合作,即使选中了Babel选项。)最后,它按升序对命中进行排序。

更新:搜索算法已更新/更正。最初,由于exec搜索任何查询变体只会根据JavaScript默认值进行迭代,因此会错过一些匹配,即在找到匹配项后,它将在 end <之后的下一个字符处开始下一次搜索上一场比赛的/ em>,例如它会在位置0和2的'aaaa'中找到'aa'。现在它在前一个匹配的 start 之后的下一个字符处开始下一次搜索,例如它现在在位置0,1和2的'aaaa'中找到'aa'。

const findAllowingOneMismatch = (target, query) => {
  const numLetters = query.length;
  const queryVariations = [];
  for (let variationNum = 0; variationNum < numLetters; variationNum += 1) {
    queryVariations.push(query.slice(0, variationNum) + "." + query.slice(variationNum + 1));
  };
  let hits = [];
  queryVariations.forEach(queryVariation => {
    const re = new RegExp(queryVariation, "g");
    let myArray;
    while ((searchResult = re.exec(target)) !== null) {
      re.lastIndex = searchResult.index + 1;
      const hit = searchResult.index;
      // console.log('found a hit with ' + queryVariation + ' at position ' + hit);
      if (hits.indexOf(hit) === -1) {
        hits.push(searchResult.index);
      }
    }
  });
  hits = hits.sort((a,b)=>(a-b));
  console.log('Found "' + query + '" in "' + target + '" at positions:', JSON.stringify(hits));
};

[
  ['abbab', 'ba'],
  ['hello', 'world'],
  ['banana', 'nan'],
  ['abcde abcxe abxxe xbcde', 'abcd'],
  ['--xx-xxx--x----x-x-xxx--x--x-x-xx-', '----']
].forEach(pair => {findAllowingOneMismatch(pair[0], pair[1])});