正则表达式:匹配包含字符串的a

时间:2011-11-07 18:55:02

标签: regex

我正在尝试匹配包含单词“Source”的所有<tr>元素,但是当其他属性(colspan / width / height,包含<td> s及其属性等)时,未知。 (我知道这可以使用javascript / jQuery选择器完成,但我只是处理非javascript上下文的HTML。)

目标示例:

<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,但不匹配第二个。

我认为这是正则表达式的原则,我可能没有抓住这里,关于贪婪或相关的东西。有什么建议吗?

2 个答案:

答案 0 :(得分:4)

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

确定你不能使用jQuery吗? :P但是严肃地说,如果我用Friedl的"unrolled loop"成语来表达它会更容易理解:

opening normal ( special normal * ) * closing
  • 开启 <tr[^>]*> - 开幕式<tr>代码

  • 正常: (?:(?!<|source)[\s\S])* - 零个或多个任何字符,前瞻以确保每次该字符不是标记的开头或单词“源“

  • 特殊: <(?!\/?tr)[^>]*> - 除了另一个开放<tr>或结束</tr>之外的任何标记。通过使用完整的标签,我们可以避免在属性的名称或值中对“source”这个词进行误报。

  • 关闭: source - 此处唯一可能遇到的问题是<tr></tr>标记,表示失败符合我们的目的。在其中一个标签之前找到“来源”是我们知道我们找到匹配的方式。 (正则表达式的其余部分[\s\S]*?<\/tr>仅使用标记的其余部分,因此您可以通过group[0]检索它。)

当然,<tr>不一定无效;它可能是嵌套TR元素的开头,可能是嵌套的TABLE元素。如果该TR包含单词“source”,则正则表达式将在单独的匹配尝试中匹配它。它只匹配最里面的完整TR标签,其中包含“source”字样。

像在HTML上使用正则表达式一样,我正在做几个简化的假设,包括格式良好,SGML评论,CDATA部分等等。警告经理

答案 1 :(得分:0)

如果你使用像jQuery这样的库,你甚至不需要使用正则表达式:

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