2011-11-07 223 views
0

我試圖匹配包含單詞「Source」的所有<tr>元素,但是當其他屬性(colspan/width/height,包含<td> s及其屬性等)是未知的。 (我知道這可以利用JavaScript/jQuery選擇做,但我只是處理對非JavaScript方面的HTML)的目標正則表達式:匹配包含字符串的<tr>

例子:

<tr> 
<td>Don't affect this</td> 
</tr> 
<tr> 
<td colspan="3" width="288" height="57"><strong>Sources:</strong> Author</td> 
</tr> 

(這就是我想要的將它更改爲:)

<tr> 
<td>Don't affect this</td> 
</tr> 
<tr class="source"> 
<td colspan="3" width="288" height="57"><strong>Sources:</strong> Author</td> 
</tr> 

下面是正則表達式模式我已經試過了都沒有奏效:

/<tr>((?:.*?)Source(?:s?):(?:.*?))<\/tr>/gmi, 

沒有匹配。

/<tr>((?:[\s\S]*?)Source(?:s?):(?:[\s\S]*?))<\/tr>/gmi, 

匹配第一個tr,但不匹配第二個。

我認爲這裏有正則表達式的原理,我可能沒有把握這裏,關於貪婪或相關的東西。有什麼建議麼?

+0

「attributes ... are unknown」 - 然後允許屬性:'/ [\ s \ S] *?Sources?:[\ s \ S] *? <\/tr>/gmi'。請注意,使用正則表達式解析HTML是一個壞主意。我發佈了這個顯示更正,但這不應該被視爲答案。 – manatwork

回答

3
/<tr[^>]*>(?:(?!<|source)[\s\S])*(?:<(?!\/?tr)[^>]*>(?:(?!<|source)[\s\S])*)*source[\s\S]*?<\/tr>/i 

肯定你不能使用jQuery這個? :P但是,嚴重的是,這將是更容易把握,如果我把它放在弗裏德爾的"unrolled loop"成語方面:

opening normal (special normal *) * closing 
  • 開口道:<tr[^>]*> - 開幕<tr>標籤

  • 正常:(?:(?!<|source)[\s\S])* - 零個或多個任意字符,向前確保每次該字符不是標籤的開頭或「源」字

  • 特殊:<(?!\/?tr)[^>]*> - 除另一個開口<tr>或關閉</tr>以外的任何標籤。通過使用完整的標籤,我們可以避免在屬性的名稱或值中出現「源」字樣的誤報。

  • 收盤:source - 它可能在這裏遇到的唯一的另一件事是<tr></tr>標籤,這表明我們的目的失敗的比賽。在之前查找「來源」其中一個標籤就是我們知道我們找到匹配的方式。 (正則表達式,[\s\S]*?<\/tr>的其餘部分,只消耗了標記,以便您可以通過group[0]檢索它的其餘部分。)

一個<tr>沒有必然無效,當然,它可能是一個嵌套TR元素的開始,大概在嵌套的TABLE元素中。如果TR包含單詞「source」,則正則表達式將在單獨的匹配嘗試中匹配它。它只會匹配最裏面的完整TR標籤與其中的「源」字。

像往常一樣在HTML中使用正則表達式的時候,我在做涉及良構,SGML註釋,CDATA節,等等等等買者自負幾個簡化的假設。

0

如果您正在使用像jQuery庫,你甚至都不需要使用正則表達式:

$('tr:contains("Source")').something... 
+0

沒錯,那可行 - 但我正在處理文本以用於非JavaScript上下文。 – supertrue

+0

@supertrue你應該把你的問題的上下文... – Neal

+0

好的,我已經添加它。 – supertrue

相關問題