Python 如何从 CSS 文件中提取所有 ID 名和 CLASS 名
有个需求,从 css 文件中提取所有 ID 名和 CLASS 名到两个 list 中
用正则可以准确的实现这个功能么?
Python 如何从 CSS 文件中提取所有 ID 名和 CLASS 名
import re
def extract_css_selectors(css_content):
"""
从CSS内容中提取所有ID选择器和CLASS选择器
参数:
css_content: CSS文件内容字符串
返回:
dict: 包含'ids'和'classes'两个键的字典
"""
# 提取ID选择器 (#开头,后跟有效CSS标识符)
id_pattern = r'#([a-zA-Z_][a-zA-Z0-9_-]*)'
ids = re.findall(id_pattern, css_content)
# 提取CLASS选择器 (.开头,后跟有效CSS标识符)
class_pattern = r'\.([a-zA-Z_][a-zA-Z0-9_-]*)'
classes = re.findall(class_pattern, css_content)
# 去重并排序
unique_ids = sorted(set(ids))
unique_classes = sorted(set(classes))
return {
'ids': unique_ids,
'classes': unique_classes
}
def extract_from_file(css_file_path):
"""
从CSS文件中提取选择器
参数:
css_file_path: CSS文件路径
返回:
dict: 包含提取结果的字典
"""
try:
with open(css_file_path, 'r', encoding='utf-8') as file:
css_content = file.read()
return extract_css_selectors(css_content)
except FileNotFoundError:
print(f"错误: 找不到文件 {css_file_path}")
return {'ids': [], 'classes': []}
except Exception as e:
print(f"读取文件时出错: {e}")
return {'ids': [], 'classes': []}
# 使用示例
if __name__ == "__main__":
# 示例CSS内容
sample_css = """
#header {
background: #333;
}
.menu-item {
color: blue;
}
#main-content .article {
padding: 10px;
}
.btn-primary, .btn-secondary {
border: 1px solid #ccc;
}
#footer .copyright {
font-size: 12px;
}
"""
# 从字符串提取
result = extract_css_selectors(sample_css)
print("提取结果:")
print(f"IDs: {result['ids']}")
print(f"Classes: {result['classes']}")
# 从文件提取(需要实际文件路径)
# file_result = extract_from_file("styles.css")
# print(f"从文件提取的IDs: {file_result['ids']}")
# print(f"从文件提取的Classes: {file_result['classes']}")
这个方案用正则表达式匹配CSS选择器,#([a-zA-Z_][a-zA-Z0-9_-]*) 匹配ID选择器,\.([a-zA-Z_][a-zA-Z0-9_-]*) 匹配CLASS选择器。函数会返回去重后的有序列表,支持从字符串或文件读取CSS内容。
正则表达式能处理大多数情况,但复杂的CSS选择器(如属性选择器、伪类)可能需要更复杂的解析。
总结:用正则匹配#和.开头的选择器就行。
classValues = re.findall(r’.([\w_-]+)’,content)
idValues = re.findall(r’#([\w_-]+)’,content)
但是会多出好多并不属于 ID 和 class 的值,
比如下面情况:
background-color: #fff;
-webkit-box-shadow: 0 0 2px 0 rgba(31, 31, 31, 0.07);
提供你一个思路,在不考虑派生选择器和注释的情况下 id 和 class 后面是要跟‘{'符号的,你这样的条件显然不够
注释可以不考虑 , 可是派生选择器 得考虑 所以我是宁可多了一些 没有少
还是没有准确得到我想要的, 但也很感谢了 提供的思路
idValues = re.findall(r’#([\w_-]+)’,content)
我想知道 我这种匹配 id 的时候 怎样能排除那种后面紧跟着着分号的:
background-color: #fff;
排除了这种 我的匹配 id 应该就准确了吧
我不确定你的文件的复杂性,但是如果是通常的写法,可以利用行头直接判断
r’^.([\w_-]+)‘
r’^#([\w_-]+)‘
都加上了’^'符号,你可以看看有没有全部选中。可以试试哈
ps: 可以在 sublime 直接能看到正则结果
因为不同的文件,正则的复杂程度是不一样的,只要针对目标写出最简单的写法,我觉得就足够了,如果你加上^还是不行的话,你可以贴出你的 css 文件一起看看怎么解决
写个 PostCSS 插件做这个事情会轻松地多


