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

Posted

技术标签:

【中文标题】如何将代码块拆分为列表?【英文标题】:How can I split code-blocks into a list? 【发布时间】:2016-10-28 00:30:33 【问题描述】:

我想将 CSS 文件的内容拆分为代码块,并使用 Python 3.5 将每个代码块推送到列表中。

所以,鉴于这个 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 来消除在拆分其中的代码块之前整理样式表的需要。

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

【问题讨论】:

What is the pythonic way to implement a css parser/replacer的可能重复 @pvg 不,很遗憾,这并没有解决我的问题。 @Mango 不需要自己实现解析器,可以用一个小库。我在下面的回答中对此进行了概述。 @Mango 确实如此,你想解决问题的方式类似于这个臭名昭著的 SO 答案***.com/a/1732454/5087125 不要这样做,使用解析器,有一些高效的小工具可以做到这一点简单而恰当。 【参考方案1】:

这个实现是使用tinycss完成的,一个简单的纯pythoncss parser。

这适用于未整理 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')])

看看不同的h1 块如何合并到一个列表中。我不太了解 CSS 的复杂性,但很容易防止这种情况发生。

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

请注意:我已将所有内容推送到字典中,但您也可以轻松地将其推送为列表。如果你想要纯列表的东西,请告诉我,但如果你明白我在做什么,这应该是相对微不足道的。

【讨论】:

正则表达式不涵盖哪些情况?假设 CSS 的格式始终正确,它应该始终可以工作 repl.it/C5ws/7 @JacobGray 假设它的格式正确。如果不是,你无论如何都需要一个解析器,所以不妨有一种方法来解决它而无需整理 css。 OP 正在询问如何拆分 formatted 一段 CSS,所以我认为可以安全地假设输入始终是格式化的。即使输入并不总是被格式化,您仍然可以将其拆分,而不管re.compile("()").split(css) 的格式如何。当您只想拆分每个规则时,我只是看不到使用库解析整个样式表的任何意义 如果存在一个额外的“空白”怎么办,您的解决方案会完全崩溃,这太安静了。注释,cmets 中的括号,cmets 中的完整块,制表符,总是有边缘情况,这样的事情使用 RegEx 绝对是个坏主意。 @MiteshNinja 谢谢你的回答,效果很好。【参考方案2】:

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

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))

输出:

>>> 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

【讨论】:

即使在整个 css 样式表中的任何地方都有一个额外的空行,这段代码也会严重中断。 @MiteshNinja 通过“可怕的中断”,我假设您的意思是 styles 中会有空行(如果您的意思是别的,请澄清)。感谢您指出了这一点。修好了。 我想你不明白。如果在任何地方都存在一个额外的空白行,您的代码现在将“可怕地”中断,除非换行符在 2 个块之间。如果块中存在额外的行,它将假定该块已完成并将其推送到styles。请重新检查您的代码。

以上是关于如何将代码块拆分为列表?的主要内容,如果未能解决你的问题,请参考以下文章

使用 webpack 代码拆分,如何加载块和 HTML 布局?

如何在 webpack 中使用 vuejs 禁用将块拆分为不同的文件?

如何将子字符串拆分为多个块并使用 C# 将它们输入到表中?

如何获取 Webpack 中每个块包含的所有文件(或模块)的列表

如何合并、拆分和查询第 k 个排序列表?

优雅的函数设计