Javascript子字符串无法提取正确的数据

时间:2019-10-09 11:50:03

标签: javascript indexof substr

我将JavaScript与indexOfsubstr结合使用,并尝试获得3个部分。

预期结果

第1部分:

<p>Some text</p>

BEFORE

第2部分:

<!-- KEYWORDS: one -->

第3部分:

<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?我需要注意某种多字节或编码问题吗?

2 个答案:

答案 0 :(得分:2)

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>

答案 1 :(得分:0)

@MauriceNino的答案是正确的。

只是称赞,我已经使用了这些信息,并从中得到了一个简短的实用函数。它返回一个具有三个块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>