Python 如何将代码块拆分为一个列表?

Python 如何将代码块拆分为一个列表?,python,css,regex,list,python-3.x,Python,Css,Regex,List,Python 3.x,我想使用Python3.5将CSS文件的内容拆分为代码块,并将每个代码块推送到一个列表中 因此,考虑到这个CSS: h1 {color: #333, background-color: transparent} h2 { font-weight:300 } h3 { font-weight: 200 } 我们可以清楚地看出,它有多种样式和/或缩进类型,这意味着CSS必须经过整理才能得到: h1 { color: #333,background-color: transparent;

我想使用Python3.5将CSS文件的内容拆分为代码块,并将每个代码块推送到一个列表中

因此,考虑到这个CSS:

h1 {color: #333, background-color: transparent}
h2 {
  font-weight:300
}
h3
{
  font-weight: 200
}
我们可以清楚地看出,它有多种样式和/或缩进类型,这意味着CSS必须经过整理才能得到:

h1 {
  color: #333,background-color: transparent;
}

h2 {
  font-weight: 300;
}

h3 {
  font-weight: 200;
}
如何使用Python读取一个整洁的CSS字符串,并将其中的每个代码块推入Python列表,如下所示:

styles = [
  "h1 {\n  color: #333,background-color: transparent;\n}",
  "h2 {\n  font-weight: 300;\n}",
  "h3 {\n  font-weight: 200;\n}"
]
我还想指出,RegExp并不是我的强项,我也不太确定使用什么RegEx,但我想我可以使用RegExp&
[].split(…)一起实现这一点

甚至可能使用RegExp来消除在拆分样式表中的代码块之前整理样式表的需要


注意:我已经检查了这个问题,但不幸的是,这也没有帮助。

这个实现是使用简单的纯python
tinycss完成的

这适用于不固定的css。只要合法

import tinycss
from collections import defaultdict

parser = tinycss.make_parser('page3')
# use parse_stylesheet_files to read from a file.
stylesheet = parser.parse_stylesheet("""h1 {color: #333; background-color: transparent}
        h2 {
              font-weight:300
        }
        h3
        {
              font-weight: 200
        }
        h1{
        padding: 0px;}
        """)

# Initialize to empty list if key does not exists
# This allows to group multiple blocks with same selectors
temp = defaultdict(list)

for rule in stylesheet.rules:
    for dec in rule.declarations:
       temp[rule.selector.as_css()].append((dec.name, dec.value.as_css()))

print(temp)
输出:

defaultdict(<class 'list'>,
            {'h1': [('color', '#333'),
                    ('background-color', 'transparent'),
                    ('padding', '0px')],
             'h2': [('font-weight', '300')],
             'h3': [('font-weight', '200')]})
>>> for s in styles: s
h1 {\n  color: #333,background-color: transparent;\n}\n
h2 {\n  font-weight: 300;\n}\n
h3 {\n  font-weight: 200;\n}\n
defaultdict(,
{'h1':[('color','#333'),
(“背景色”、“透明”),
('padding','0px'),
'h2':[('font-weight','300'),
'h3':[('font-weight','200')]]
查看不同的
h1
块是如何加入到单个列表中的。我并不十分清楚CSS的复杂性,但很容易防止这种情况发生

与正则表达式的解决方案不同,它更灵活,因为它涵盖了所有边缘情况,可与选择器、CSS2和CSS3一起使用


请注意:我已经把所有的东西都放到了字典里,但是你也可以很容易地把它作为一个列表。如果您想要纯列表,请告诉我,但如果您了解我在做什么,这应该相对简单。

您可以通过简单的文件读取和替换来实现这一点:

styles = []
with open('file.css') as file:
    style = []
    for line in file.readlines():
        # If line is empty
        if not line.strip():
            # If a block is non-empty
            if style:
                styles.append("".join(style))
                style = []
        else:
            # Add to the current block
            style.append(line)
    styles.append("".join(style))
输出:

defaultdict(<class 'list'>,
            {'h1': [('color', '#333'),
                    ('background-color', 'transparent'),
                    ('padding', '0px')],
             'h2': [('font-weight', '300')],
             'h3': [('font-weight', '200')]})
>>> for s in styles: s
h1 {\n  color: #333,background-color: transparent;\n}\n
h2 {\n  font-weight: 300;\n}\n
h3 {\n  font-weight: 200;\n}\n

@pvg No的可能重复,不幸的是,这并没有解决我的问题。@Mango不需要自己实现解析器,您可以使用一个小库。我已经在下面的回答中对其进行了概述。@Mango事实上是这样的,你想要解决问题的方式类似于这个臭名昭著的答案,所以不要这样做,使用解析器,有一些小的高效的解析器可以简单而正确地这样做。正则表达式不包括哪些情况?假设CSS的格式总是正确的,假设它的格式是正确的,它应该总是工作。如果不是,你无论如何都需要一个解析器,所以最好有一种不用整理css就可以解决它的方法。OP是问如何分割css的格式化部分,所以我认为假设输入总是格式化的是安全的。即使输入不总是格式化,您仍然可以通过
re.compile(“(})”).split(css)
将其拆分,而不管格式如何。我只是不认为使用库来解析整个样式表有任何意义,因为您只需要拆分每个规则。如果存在一个额外的“空白”,那么您的解决方案会完全分离,而且也会非常安静。注释,注释中的括号,注释中的完整块,制表符,总是有边缘大小写,使用正则表达式来处理这样的事情绝对不是一个好主意。@MiteshNinja谢谢你的回答,它工作得非常出色。即使在整个css样式表中的任何位置都有一个额外的空行,此代码也会非常糟糕。@MiteshNinja所说的“非常糟糕”,我想你的意思是在
样式中会有空行(如果你是指其他内容,请澄清)。谢谢你指出这一点。修好了,我想你不明白。如果有一个额外的空行出现在任何地方,你的代码就会“可怕地”中断,除非换行符在两个块之间。如果一个块中有一个额外的行,它将假定该块已完成,并将其推到
样式上。请重新检查您的代码。