在网页解析、文本内容提取等场景中,我们常常需要从一段HTML文本里提取出带有特定类名的div标签内的所有内容。正则表达式作为文本匹配的高效工具,能够快速完成这类提取任务,但是div标签的属性顺序不固定、可能存在嵌套结构,直接使用简单的匹配规则很容易出现错误。下面我们就一步步讲解如何用正则表达式精准实现这个需求。

基础匹配规则说明
首先我们要明确div标签的基本结构,一个标准的div标签可能包含多个属性,类名只是其中一个属性,例如:
<div class="target-class" id="test">这是要提取的内容</div> <div id="test" class="target-class other-class">包含多个类名的div内容</div>
类名可能出现的位置不固定,也可能一个div包含多个类名,所以匹配的时候不能固定class属性的位置,也不能假设类名是唯一的属性。
匹配class属性的正则写法
要匹配特定类名,首先需要正确匹配class属性,假设我们要提取类名包含target-class的div内容,class属性的匹配规则可以写成:
classs*=s*["']?target-class["']?(s+|$)
这个规则的含义是:先匹配class字符串,后面可以有任意数量的空白字符,然后是等号,等号后面也可以有任意数量的空白字符,接着是可选的引号,然后是目标类名target-class,后面要么是引号,要么是空白字符或者字符串结束,这样可以避免匹配到类似target-class-extra这样的其他类名。
完整的正则匹配表达式
结合div标签的整体结构,我们可以写出完整的匹配表达式,这里需要注意避免贪婪匹配导致的跨标签匹配问题:
<div[^>]*classs*=s*["'][^"']*target-class[^"']*["'][^>]*>([sS]*?)</div>
表达式各部分含义说明:
<div[^>]*:匹配开头的div标签,后面直到出现>之前的所有非>字符,也就是div的所有属性部分classs*=s*["'][^"']*target-class[^"']*["']:匹配包含目标类名的class属性,允许类名前后有其他类名[^>]*>:匹配div标签剩余属性和右尖括号([sS]*?):非贪婪匹配div标签内部的所有内容,直到遇到第一个</div></div>:匹配闭合的div标签
代码示例
JavaScript实现示例
在JavaScript中可以使用match方法或者exec方法配合正则完成提取:
const htmlStr = `
<div class="other">不需要的内容</div>
<div class="target-class">第一个目标div的内容</div>
<div id="test" class="target-class other">第二个目标div的内容</div>
<div class="target-class">
第三个目标div的内容
<span>内部嵌套标签</span>
</div>
`;
// 定义正则,注意使用g修饰符匹配所有符合条件的div
const reg = /<div[^>]*classs*=s*["'][^"']*target-class[^"']*["'][^>]*>([sS]*?)</div>/g;
const result = [];
let match;
// 循环提取所有匹配的内容
while ((match = reg.exec(htmlStr)) !== null) {
// match[1]就是div内部的内容
result.push(match[1].trim());
}
console.log(result);
// 输出结果:
// [
// "第一个目标div的内容",
// "第二个目标div的内容",
// "第三个目标div的内容n <span>内部嵌套标签</span>"
// ]
Python实现示例
Python中可以使用re模块完成正则匹配:
import re html_str = """ <div class="other">不需要的内容</div> <div class="target-class">第一个目标div的内容</div> <div id="test" class="target-class other">第二个目标div的内容</div> <div class="target-class"> 第三个目标div的内容 <span>内部嵌套标签</span> </div> """ # 定义正则,使用re.DOTALL让.匹配换行符,相当于[sS] reg = r'<div[^>]*classs*=s*["'][^"']*target-class[^"']*["'][^>]*>(.*?)</div>' # 使用findall提取所有匹配的内容 result = re.findall(reg, html_str, re.DOTALL) # 去除每个结果的首尾空白 result = [item.strip() for item in result] print(result) # 输出结果: # [ # '第一个目标div的内容', # '第二个目标div的内容', # '第三个目标div的内容n <span>内部嵌套标签</span>' # ]
注意事项
- 如果目标div内部还有嵌套的div标签,上面的非贪婪匹配会只匹配到第一个闭合的</div>,导致内容提取不完整,这种情况建议使用HTML解析库(如Python的BeautifulSoup、JavaScript的DOMParser)处理,正则更适合结构简单、无嵌套的场景。
- 正则中的特殊字符都需要转义,比如
.、/、(、)等,写正则的时候要注意不要遗漏转义符。 - 如果HTML文本中的class属性使用的是单引号,上面的正则已经做了兼容处理,不需要额外修改规则。
- 如果目标类名是动态变化的,可以把类名部分做成变量,拼接成正则字符串即可。
总结:使用正则表达式提取含特定类名的div内容,核心是正确匹配class属性的位置和多类名情况,同时避免贪婪匹配带来的误差,在简单场景下正则能够快速完成任务,复杂嵌套场景建议结合专业的HTML解析工具使用。