簡體   English   中英

如果開頭標簽已指定類,則Javascript RegExp會替換兩個標簽之間的文本

[英]Javascript RegExp replace text between two tags if the opening tag has specified class

我有以下HTML代碼:

<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span>

我想替換span標簽之間的文本,但是僅當span標簽具有類“ search-text ”時才可以 因此,就我而言,我有一個包含兩個跨度的HTML代碼的字符串。 如果它包含搜索到的文本,我想替換第二個跨度中的文本。

我搜索:“ aa ”,我想用<span class="highlight-text">aa</span>替換它。 因此,最終結果應為:

<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text <span class="highlight-search">AA</span>A</span>

現在我正在做類似的事情:

var paint = $.proxy(this._paint, this);
var regex = /(<span class="search-text[^>]+>|<\/span>)/g;
item.node.innerHTML = item.html.replace(regex, paint);

其中“ value ”是:“ aa ”和“ item.html ”是在我的問題開頭出現的HTML。

_paint函數:

_paint: function($0) {
   return '<span class="highlight-text">' + $0 + '</span>';
},

這時的結果是第二個跨度被完全包裹在'<span class="highlight-text">' + $0 + '</span>'; 結果如下:

<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="highlight-text"><span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span></span>

我只希望將文本匹配項包裝在hghlight跨度內,如下所示:

<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span>
<span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text <span class="highlight-text">AA</span>A</span>

有任何想法嗎? 謝謝。

眾所周知 ,正則表達式是大多數工作的錯誤工具。 它是為處理字符串而不是HTML之類的結構化數據而設計的。 幸運的是,您已經在瀏覽器中,因此您擁有一個為DOM操作設計的完整工具集:也可以使用它。 (您還用jQuery標記了問題,這使它變得更加容易。)

更新:我會誤解問題的詳細信息,並且是從父節點的屬性中而不是從外部拉出搜索字符串。 我也未能使搜索不區分大小寫。 現在都在以下內容中進行了更正:

 // Make a case-insensitive regex from the search string let str = 'aa'; let re = new RegExp(str, "gi"); // operate only on the .search-text nodes: $('.search-text').each(function(i, el) { // get the current contents of the element: let text = $(el).html(); // Add your highlights: text = text.replace(re, '<span class="highlight-text">$&</span>'); // insert the modified text back into the DOM: $(el).html(text); }) 
 .highlight-text { background-color: #FFC } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span> <span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span> I 

僅當.search-text元素沒有子節點時,這才是真正安全的。 即使它們包含一些HTML,它通常也可以工作,但前提是:

  • 您可以確定要突出顯示的字符串永遠不會與HTML本身的某些部分匹配,並且
  • DOM元素上沒有任何事件綁定(此腳本替換了.search-text Wholesale的內容。)

例如,嘗試在包含<span>元素的html字符串中突出顯示單詞“ span”會導致無效的html:

 // same script as above $('.search-text').each(function(i, el) { let text = $(el).html(); let highlights = $(el).attr("attribute").split(" "); for (str of highlights) { text = text.replace(str, '<span class="highlight-text">' + str + '</span>'); } $(el).html(text); }) 
 .highlight-text { background-color: #FFC } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <span class="search-text" attribute="span">Text AAA <span>test</span></span> 

以字符串開頭

如果您的起點是HTML字符串而不是已經構建的DOM樹,那么您要做的就是首先將該字符串轉換為文檔片段,以便可以在其上使用以下DOM工具:

let fragment = $('<template>');
fragment.html($yourStringHere);
/* manipulate fragment contents as above, then */
return fragment.html();

受Daniel Beck的答案啟發的部分解決方案。 此解決方案不操縱DOM。 (我只是將結果顯示在DOM上以進行演示)

https://jsfiddle.net/mt2yz90L/3/

HTML:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="result">
</div>

JS:

  let searchedText = 'aa';
  let html ='<span class="whatever-class custom-class-name" attribute="Whatever 1 AAA">AAA BBB</span><span class="search-text custom-class-name" attribute="Whatever 2 AAA">Text AAA</span> I';
  var htmlParts = html.split(/(<span class="search-text[^>]+>|<\/span>)/g);
  var htmlPartsIndex = 0;
  for(var i=0; i < htmlParts.length; i++) {
    if(htmlParts[i].indexOf('search-text') !== -1) {
        htmlPartsIndex = ++i;
      break;
    }
  }
  if(htmlPartsIndex > 0) {
     htmlParts[htmlPartsIndex] = htmlParts[htmlPartsIndex].toLowerCase().replace(searchedText, '<span class="highlight-text">' + searchedText + '</span>')
  }
  $('#result').html(htmlParts.join(''));

CSS:

.highlight-text {
  background-color: red;
}

我唯一的問題是,就我而言(要解析的項目超過300個),它阻止了瀏覽器。 所以這很慢。 我發布它的想法是,也許有人會分享更快的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM