Javascript子串没有提取正确的数据

Javascript substring does not extract the correct data

我将 javascript 与 indexOfsubstr 一起使用,我尝试得到 3 个部分。

预期结果

第 1 部分:

<p>Some text</p>

BEFORE

第 2 部分:

<!-- KEYWORDS: one -->

第三部分:

<p>Some more text</p>

实际效果

运行 下面的代码和控制台日志,你会看到这些部分到处都是。

class Inside {
  getPos(selector, startsWith, endsWith) {
    const html = document.querySelector(selector).innerHTML;
    let data = {};
    data.pos = {};
    data.html = {};

    data.pos.start = html.indexOf(startsWith);
    data.pos.end = html.indexOf(endsWith, data.pos.start);
    data.pos.finish = html.length;

    data.html.before = html.substr(0, data.pos.start);
    data.html.match = html.substr(data.pos.start, data.pos.end);
    data.html.after = html.substr(data.pos.end, data.pos.finish);

    console.log(data.pos);
    console.log(data.html.before);
    console.log(data.html.match);
    console.log(data.html.after);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  const InsideObj = new Inside();
  InsideObj.getPos('main', '<!-- KEYWORDS:', '-->');
});
<main>
   <p>Some text</p>

   BEFORE
   <!-- KEYWORDS: one -->
   AFTER

    <p>Some more text</p>
  </main>

问题

我不明白为什么它不相加。是 substr 还是 indexOf?这是我需要注意的某种多字节或编码问题吗?

substr() 不占用两个字符串位置,而是占用一个位置和一个长度,如下所示:substr(startingPosition, subLength).

这是一个简化的例子:

let str = 'Hello Test';

let startPos = 3, endPos = 5; // We expect a string with 2 chars starting from the 3nd position

console.log(str.substr(startPos, endPos)); // WRONG! 
console.log(str.substr(startPos, endPos - startPos));

这是您的固定代码: 您需要从结束位置减去起始位置,以获得两者之间的长度(如上例所示)。另外,您需要考虑搜索参数本身的长度。

class Inside {
  getPos(selector, startsWith, endsWith) {
    const html = document.querySelector(selector).innerHTML;
    let data = {};
    data.pos = {};
    data.html = {};

    data.pos.start = html.indexOf(startsWith);
    data.pos.end = html.indexOf(endsWith, data.pos.start);
    data.pos.finish = html.length;

    data.html.before = html.substr(0, data.pos.start);
    
    // From the start position to end - start plus the length of the string you searched
    data.html.match = html.substr(data.pos.start, data.pos.end - data.pos.start + endsWith.length);
    
    // From the end position + the length of the string you searched to finish - end
    data.html.after = html.substr(data.pos.end + endsWith.length, data.pos.finish - data.pos.end);

    console.log(data.pos);
    console.log(data.html.before);
    console.log(data.html.match);
    console.log(data.html.after);
  }
}

document.addEventListener("DOMContentLoaded", () => {
  const InsideObj = new Inside();
  InsideObj.getPos('main', '<!-- KEYWORDS:', '-->');
});
<main>
   <p>Some text</p>

   BEFORE
   <!-- KEYWORDS: one -->
   AFTER

    <p>Some more text</p>
  </main>

@MauriceNino 的回答是正确的。

作为恭维,我已经使用了该信息并从中制作了一个简短的实用程序函数。它 returns 具有三个块的对象,beforeaftermatch

function getChunks(selector, strStart, strEnd) {
  const html = document.querySelector(selector).innerHTML;
  const start = html.indexOf(strStart);
  const end = html.indexOf(strEnd, start);

  if (start == -1 || end == -1) return;

  return {
    before: html.substr(0, start),
    match: html.substr(start, end - start + strEnd.length),
    after: html.substr(end + strEnd.length, html.length - end)
  };
}

let chunks = getChunks('main', '<!-- KEYWORDS:', '-->');
console.log(chunks);
<main>
  <p>Some text

  BEFORE
  <!-- KEYWORDS: one -->
  AFTER

  <p>Some more text</p>
</main>