如何使用Javascript仅在HTML字符串的文本部分查找子字符串?

如何使用Javascript仅在HTML字符串的文本部分查找子字符串?,javascript,html,string,Javascript,Html,String,更新:我不再特别需要这个问题的答案-我能够以完全不同的方式解决(更大的)问题(见我的评论)。不过,我会偶尔检查一下,如果有可行的答案,我会接受。(不过可能需要一到三个星期,因为我只是偶尔来这里。) 我有一根绳子。它可能有也可能没有HTML标记。因此,它可能是: 'This is my unspanned string' '<span class="someclass">This is my spanned string</span>' 或者可以是: 'This is

更新:我不再特别需要这个问题的答案-我能够以完全不同的方式解决(更大的)问题(见我的评论)。不过,我会偶尔检查一下,如果有可行的答案,我会接受。(不过可能需要一到三个星期,因为我只是偶尔来这里。)

我有一根绳子。它可能有也可能没有HTML标记。因此,它可能是:

'This is my unspanned string'
'<span class="someclass">This is my spanned string</span>'
或者可以是:

'This is my unspanned string'
'<span class="someclass">This is my spanned string</span>'
“这是我的跨距字符串”
或:

“这是我的跨距字符串”
或:

“这是我的跨距字符串”
我想找到子字符串的索引,但只在字符串的部分中找到,如果该字符串被转换为DOM元素,则该部分将是(一个)文本节点。在本例中,仅在字符串中包含纯文本的部分
这是我的字符串

但是,我需要整个字符串中的子字符串位置,而不仅仅是纯文本部分

因此,如果我在上面的每个字符串中搜索“span”:

  • 搜索第一个将返回13(基于0)
  • 搜索第二个将跳过字符串中的开头
    span
    标记,并为单词
    span
    中的字符串
    span
    返回35
  • 搜索第三个将跳过空的
    span
    标记和两个嵌套的
    span
    标记的开口,并返回91
  • 搜索第四个将跳过嵌套的
    span
    标记和打开第二个
    span
    标记,并返回100
我不想删除任何HTML标记,我只是不想在搜索中包含它们

我知道尝试使用正则表达式几乎是肯定的,甚至可能是对于我的代码将遇到的过于简单的字符串,所以请不要建议使用正则表达式

我猜我需要使用HTML解析器(这是我以前从未做过的)。是否有一个可以访问每个节点的原始解析字符串(或至少其长度)

有没有比这更简单的解决办法


我确实四处搜索过,以前找不到任何人问过这个问题,所以如果有人知道我遗漏了什么,我为错误的搜索技巧道歉。

搜索可以逐字符循环字符串。如果在标记内部,则跳过标记,仅在标记外部搜索字符串,并记住部分匹配。如果文本部分匹配,然后被另一个标记打断,则在标记外部继续搜索。

搜索可以逐字符循环搜索字符串。如果在标记内部,则跳过标记,仅在标记外部搜索字符串,并记住部分匹配(如果文本部分匹配,然后被另一个标记打断),在标记外部继续搜索。

您可以使用浏览器自己的HTML解析器和XPath引擎仅在文本节点内部搜索,并执行所需的任何处理

以下是部分解决方案:

var haystack = '  <span class="no-text"></span><span class="some-class"><span class="other-class">This is my spanned string</span></span>';
var needle = 'span';

var elt = document.createElement('elt');
elt.innerHTML = haystack;

var iter = document.evaluate('.//text()[contains(., "' + needle + '")]', elt).iterateNext();

if (iter) {
    var position = iter.textContent.indexOf(needle);
    var range = document.createRange();
    range.setStart(iter, position);
    range.setEnd(iter, position + needle.length);
    // At this point, range points at the first occurence of `needle`
    // in `haystack`. You can now delete it, replace it with something
    // else, and so on, and after that, set your original string to the
    // innerHTML of the document fragment representing the range.
    console.log(range);
}
var haystack='这是我的跨距字符串';
var针='span';
var elt=document.createElement('elt');
elt.innerHTML=干草堆;
var iter=document.evaluate('.//text()[包含(,““+pinder+”)”),elt.iterateNext();
国际热核聚变实验堆{
var位置=iter.textContent.indexOf(指针);
var range=document.createRange();
量程设置启动(iter,位置);
设定范围(iter,位置+针长度);
//此时,范围点在“针”的第一次出现时`
//在“haystack”中。您现在可以删除它,并将其替换为其他内容
//然后,将原始字符串设置为
//表示范围的文档片段的innerHTML。
控制台日志(范围);
}

您可以使用浏览器自己的HTML解析器和XPath引擎仅在文本节点内搜索,并执行所需的任何处理

以下是部分解决方案:

var haystack = '  <span class="no-text"></span><span class="some-class"><span class="other-class">This is my spanned string</span></span>';
var needle = 'span';

var elt = document.createElement('elt');
elt.innerHTML = haystack;

var iter = document.evaluate('.//text()[contains(., "' + needle + '")]', elt).iterateNext();

if (iter) {
    var position = iter.textContent.indexOf(needle);
    var range = document.createRange();
    range.setStart(iter, position);
    range.setEnd(iter, position + needle.length);
    // At this point, range points at the first occurence of `needle`
    // in `haystack`. You can now delete it, replace it with something
    // else, and so on, and after that, set your original string to the
    // innerHTML of the document fragment representing the range.
    console.log(range);
}
var haystack='这是我的跨距字符串';
var针='span';
var elt=document.createElement('elt');
elt.innerHTML=干草堆;
var iter=document.evaluate('.//text()[包含(,““+pinder+”)”),elt.iterateNext();
国际热核聚变实验堆{
var位置=iter.textContent.indexOf(指针);
var range=document.createRange();
量程设置启动(iter,位置);
设定范围(iter,位置+针长度);
//此时,范围点在“针”的第一次出现时`
//在“haystack”中。您现在可以删除它,并将其替换为其他内容
//然后,将原始字符串设置为
//表示范围的文档片段的innerHTML。
控制台日志(范围);
}

以下是我想出的一个小功能:

function customSearch(haysack,needle){
    var start = 0;
    var a = haysack.indexOf(needle,start);
    var b = haysack.indexOf('<',start);

    while(b < a && b != -1){
        start = haysack.indexOf('>',b) + 1;
        a = haysack.indexOf(needle,start);
        b = haysack.indexOf('<',start);
    }

    return a;
}
功能自定义搜索(草袋、针){
var start=0;
var a=haysack.indexOf(针,开始);
VarB=haysack.indexOf('',b)+1;
a=干草袋指数(针,开始);

b=haysack.indexOf(“这里是我想到的一个小函数:

function customSearch(haysack,needle){
    var start = 0;
    var a = haysack.indexOf(needle,start);
    var b = haysack.indexOf('<',start);

    while(b < a && b != -1){
        start = haysack.indexOf('>',b) + 1;
        a = haysack.indexOf(needle,start);
        b = haysack.indexOf('<',start);
    }

    return a;
}
功能自定义搜索(草袋、针){
var start=0;
var a=haysack.indexOf(针,开始);
VarB=haysack.indexOf('',b)+1;
a=干草袋指数(针,开始);

b=haysack.indexOf(“让我们从第三个示例开始:

var desiredSubString = 'span';
var entireString = '<span class="no-text"></span><span class="some-class"><span class="other-class">This is my spanned string</span></span>';
然后,您可以在
entireString
中找到
文本字符串开头的索引:

var textString = entireString.replace(/(data-([^"]+"[^"]+")/ig,"");
textString = textString.replace(/(<([^>]+)>)/ig,"");
var indexOfTextString = entireString.indexOf(textString);
var indexOfSubStringWithinTextString = textString.indexOf(desiredSubString);
然后,您可以在
文本字符串中找到要查找的子字符串开头的索引:

var textString = entireString.replace(/(data-([^"]+"[^"]+")/ig,"");
textString = textString.replace(/(<([^>]+)>)/ig,"");
var indexOfTextString = entireString.indexOf(textString);
var indexOfSubStringWithinTextString = textString.indexOf(desiredSubString);
最后,您可以同时添加
indexOfTextString
indexOfSubStringWithinTextString

var indexOfSubString = indexOfTextString + indexOfSubStringWithinTextString;
将所有内容放在一起:

var entireString = '<span class="no-text"></span><span class="some-class"><span class="other-class">This is my spanned string</span></span>';
var desiredSubString = 'span';

var textString = entireString.replace(/(data-([^"]+"[^"]+")/ig,"");
textString = textString.replace(/(<([^>]+)>)/ig,"");

var indexOfTextString = entireString.indexOf(textString);
var indexOfSubStringWithinTextString = textString.indexOf(desiredSubString);
var indexOfSubString = indexOfTextString + indexOfSubStringWithinTextString;
var entireString='这是我的跨距字符串';
var desiredSubString='span';
var textString=entireString.replace(/(数据-([^“]+”[^“]+”)/ig“”;
textString=textString.replace(/(]+)>)/ig,“”;
var indexOfTextString=entireString.indexOf(textString);
var IndexOfsubstringwiti