如何捕获两个标记之间的字符串

时间:2015-05-08 18:22:39

标签: javascript jquery

我正在编写一个书签,以增强我的工作流程。我的部分工作是获取要放入电子邮件的正确信息。我喜欢JavaScript和jQuery,所以我正在努力使用这个库让我的工作更轻松。

我的目标是一个特别奇怪的标记网站。我需要在匹配的标签标签之后以及下一个标签标签之前捕获文本。奇怪的是,在P标签内部就是这样。我不知道为什么网站的开发人员决定使用标签标签......我无法修改标记,所以这不是一个选项。我在网上搜索过,并且无法找到适合我特定情况的工作技术。

我创建了一个jsFiddle来演示我正在尝试使用相同类型的标记和CSS。我没有问题访问标签,我已经使用了一些不同的方法(在小提琴,注释掉)但我仍然无法正确“捕获”两个标签之间的文本。该文本最终会被置于警报中,因此我可以快速复制它。我已经尝试过使用.nextUntil,但没有运气。

基本上它会是这样的:

<label>item 1</label> Content to capture
<br><br>
<label>item 2</label> Don't capture this...

我担心我的尝试不起作用的原因是因为(我认为)nextUntil()尝试使用初始选择器找到下一个对象,所以它正在寻找下一个标签,而不是两者之间的文本。我尝试过使用$('selector').parent().nextUntil('label')但也没用过。

以下是工作示例:

$(document).ready(function(){
  //$('p label:eq(0)')afterUntil('<br>').css('color', 'red');
  //$('p').find($('label:contains("item 1")')).nextUntil("<label>").css('color', 'red');
  $('p label:contains("item 1")').parent().nextUntil('label').css('color','red');
});
label {
  display:inline-block;    
  width:25%;
  font-weight:bold;
}
p {
  font-family:arial;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p>
  <label>item 1</label> Capture me!<br><br>
  <label>item 2</label> Don't capture me
</p>
小提琴:http://jsfiddle.net/1c2LpzrL/1/

6 个答案:

答案 0 :(得分:1)

$('p label:contains("item 1")').prop('nextSibling')将在标签后选择该文本节点。

如果你想使用css设置样式,那么你必须使用jQuery将该文本包装在一个范围内并将css颜色设置为红色。对<p>标签上的内容进行着色或着色为红色,并将该标签的颜色设置为原始颜色。

另请注意,从.nextSibling返回的内容将是文本节点,而不是jQuery对象。

答案 1 :(得分:1)

您可以将<p>标记内的HTML视为字符串,然后在substring和第一个</label>之间获取<br>

var totalText = $("p").html();
//determine start-pos and end-pos of desired substring, and then get it
var startPos = totalText.indexOf("</label>") + "</label>".length;
var endPos = totalText.indexOf("<br");
var targetText = totalText.substring(startPos,endPos).trim();

小提琴:http://jsfiddle.net/3uw8ux9t/3/

  1. startPos找到第一个"</label>"的位置,然后将"</label>"的长度添加到该位置。
  2. endPos找到第一个"<br"的位置(我离开了结束>,因为正式拼写为<br />,我的方式允许两种拼写方式)。
  3. targetText最终获取startPosendPos的子字符串。
    .trim()从新字符串的开头和结尾删除所有空格)

    • console.log(targetText)给出:

        

      抓住我!

    •   

  4. UPDATE:

    在您发表评论后,我重写了我的脚本以满足您的指定需求:

    $(document).ready(function(){
      function getUnenclosedText(selector,pointer,tag) {
        var str = $(selector).html();
        //determine start-pos and end-pos
        var startPos = str.indexOf(pointer+"</"+tag+">") + (pointer+"</"+tag+">").length;
        var endPos = str.indexOf("<"+tag,startPos);
        //if there are line-breaks, reset end-pos
        if (str.indexOf("<br",startPos)<endPos || endPos==-1) {
          endPos = str.indexOf("<br",startPos);
        }
        //return substring
        if (endPos==-1) {return str.substring(startPos).trim();} //if it was the last text in the container
        else {return str.substring(startPos,endPos).trim();}
      }
      
      console.log(getUnenclosedText("p","item 1","label")); //(selector,pointer,pointerTag)
      alert('Item 1: '+getUnenclosedText("p","item 1","label") +'\n'+ 'Item 3: '+getUnenclosedText("p","item 3","label"));
    });
    p {
      font-family:arial;
    }
    
    label {
      display:inline-block;    
      width:25%;
      font-weight:bold;
    }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <p>
      <label>item 1</label> Capture me!
      <br /><br />
      <label>item 2</label> Don't capture me
      <label>item 3</label> capture me as well
      <br /><br />
      <label>item 4</label> Don't capture me either
    </p>
    小提琴:http://jsfiddle.net/3uw8ux9t/9/

    我尝试使用所有参数的变量使其尽可能可扩展,以便脚本不再限于<p><label>

    • 每次要提取一段文本时,您现在必须调用函数getUnenclosedText(selector,pointer,tag)。这三个参数使函数可伸缩,因此您可以在各种元素上使用它,而不仅仅是<label>中的<p>
      • "selector"指定要在其上执行功能的容器元素。因此,如果您有多个具有不同ID的<p>代码,则可以使用其jQuery选择器(例如<p>)访问特定的"p#someid"代码。
      • "pointer"指定您想要提取未封闭文本的文本(例如"item 1""item 2")。
      • "tag"指定包含指针的标记类型(例如"label""span")。

    如果您有任何问题,请在评论中询问他们,如果需要,我会回复或更新此答案,但我认为您可以在互联网上找到您需要的大部分内容。
    阅读this有关如何使用indexOf()的信息,您将了解代码中最困难的部分。

答案 2 :(得分:0)

您只能使用jQuery来获取该特定文本,因为它只处理元素。您需要的文本位于元素之间,而父元素包含的文本比您想要的多。

您可以从该标签获取DOM节点,直到下一个标签,并从中获取文本内容。

在您的示例中,标签之间有两个文本节点和两个br元素,因此您需要根据br元素确定所需内容。在示例中,我已将它们翻译为文本中的换行符:

var e = $('p label:eq(0)')[0].nextSibling;
var s = '';
while (e.tagName != 'LABEL') {
    if (e.tagName == 'BR') {
        s += '\n';
    } else {
        s += e.nodeValue;
    }
    e = e.nextSibling;
}
console.log(s);

演示:http://jsfiddle.net/Guffa/1c2LpzrL/3/

答案 3 :(得分:0)

jsfiddle DEMO

function captureStr(p, itm) {
    if(p.find('label').length > 0 && p.find('label:eq(0)').text().indexOf(itm) >= 0)
        return p.html().split("<br>")[0].split("</label>")[1].trim();
}

测试:

console.log(captureStr($('p'), "item 1"));
  

抓住我!

如果你有很多这样的结构,那么你可以循环并为每个结构调用函数。

答案 4 :(得分:0)

假设结构与您提出的结构没有太大变化,下面将根据下一个兄弟不为空将节点写入控制台。我认为这应该与你在任意数量的段落标签中使用的标签一样多。这是一个有效的JSFiddle(http://jsfiddle.net/RVAProgrammer/jsqxfgxe/

console.log($('p').contents().filter(function () {
    var isTextNode = this.nodeType === Node.TEXT_NODE

    if (isTextNode) {
       if ($(this)[0].nextElementSibling === null) {
          return false;
       }
      return true;
    }

    return false;
}).text());

答案 5 :(得分:0)

如果问题是在标签之间找到文本/ HTML,您可以将标签标签的原始HTML文本拆分为数组。

var items = paragraphNode.innerHTML.split(/<label>[\s\S]*?<\/label>/g);

此解决方案的优点在于可以轻松更改正则表达式以支持其他标记或更复杂的结构。

演示在这里: http://jsfiddle.net/x2u8ysx2/