这是我的第一个问题!
到了这一点;
在正则表达式方面,我很陌生.
为了更好地学习并创建我可以实际使用的东西,我正在尝试创建一个可以在CSS文件中找到所有CSS标记的正则表达式.
到目前为止,我正在使用:
[#.]([a-zA-Z0-9_\-])*
Run Code Online (Sandbox Code Playgroud)
哪个工作得很好,并找到了#TB_window以及#TB_window img#TB_Image和.TB_Image#TB_window.
问题是它还在CSS文件中找到了十六进制代码标记.即#FFF或#eaeaea.
还可以找到.png或.jpg或0.75 ..
实际上,找到它们是合乎逻辑的,但是不是那里有明智的解决方法吗?
喜欢在括号之间排除任何东西{..}?
(我很确定这是可能的,但我的正则表达式经验还不多).
提前致谢!
干杯!
麦克风
CSS 是一种非常简单的正则语言,这意味着它可以完全由正则表达式解析。它只有一组选择器,每个选择器后面跟着一组用冒号分隔的选项。
请注意,本文中的所有正则表达式都应设置verbose和dotall标志(某些语言中为 /s 和 /x,Python 中为 re.DOTALL 和 re.VERBOSE)。
获取(选择器、规则)对:
\s* # Match any initial space
([^{}]+?) # Ungreedily match a string of characters that are not curly braces.
\s* # Arbitrary spacing again.
\{ # Opening brace.
\s* # Arbitrary spacing again.
(.*?) # Ungreedily match anything any number of times.
\s* # Arbitrary spacing again.
\} # Closing brace.
Run Code Online (Sandbox Code Playgroud)
img[src~='{abc}']在属性选择器(例如)或规则(例如)中包含带引号的大括号的极少数情况下,这将不起作用background: url('images/ab{c}.jpg')。这可以通过使正则表达式更加复杂来解决:
\s* # Match any initial space
((?: # Start the selectors capture group.
[^{}\"\'] # Any character other than braces or quotes.
| # OR
\" # An opening double quote.
(?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character.
\" # And a closing double quote.
| # OR
\'(?:[^\']|\\.)*\' # Same as above, but for single quotes.
)+?) # Ungreedily match all that once or more.
\s* # Arbitrary spacing again.
\{ # Opening brace.
\s* # Arbitrary spacing again.
((?:[^{}\"\']|\"(?:[^\"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')*?)
# The above line is the same as the one in the selector capture group.
\s* # Arbitrary spacing again.
\} # Closing brace.
# This will even correctly identify escaped quotes.
Run Code Online (Sandbox Code Playgroud)
哇,那是少数。但如果您以模块化方式处理它,您会发现它并不像乍一看那么复杂。
现在,为了分割选择器和规则,我们必须匹配非分隔符的字符串(其中分隔符是选择器的逗号和规则的分号)或带引号的字符串及其内部的任何内容。我们将使用上面使用的相同模式。
对于选择器:
\s* # Match any initial space
((?: # Start the selectors capture group.
[^,\"\'] # Any character other than commas or quotes.
| # OR
\" # An opening double quote.
(?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character.
\" # And a closing double quote.
| # OR
\'(?:[^\'\\]|\\.)*\' # Same as above, but for single quotes.
)+?) # Ungreedily match all that.
\s* # Arbitrary spacing.
(?:,|$) # Followed by a comma or the end of a string.
Run Code Online (Sandbox Code Playgroud)
对于规则:
\s* # Match any initial space
((?: # Start the selectors capture group.
[^,\"\'] # Any character other than commas or quotes.
| # OR
\" # An opening double quote.
(?:[^\"\\]|\\.)* # Either a neither-quote-not-backslash, or an escaped character.
\" # And a closing double quote.
| # OR
\'(?:[^\'\\]|\\.)*\' # Same as above, but for single quotes.
)+?) # Ungreedily match all that.
\s* # Arbitrary spacing.
(?:;|$) # Followed by a semicolon or the end of a string.
Run Code Online (Sandbox Code Playgroud)
最后,对于每个规则,我们可以在冒号上拆分(一次!)以获得属性值对。
将它们全部放到一个 Python 程序中(正则表达式与上面相同,但为了节省空间而不再冗长):
import re
CSS_FILENAME = 'C:/Users/Max/frame.css'
RE_BLOCK = re.compile(r'\s*((?:[^{}"\'\\]|\"(?:[^"\\]|\\.)*"|\'(?:[^\'\\]|\\.)*\')+?)\s*\{\s*((?:[^{}"\'\\]|"(?:[^"\\]|\\.)*"|\'(?:[^\'\\]|\\.)*\')*?)\s*\}', re.DOTALL)
RE_SELECTOR = re.compile(r'\s*((?:[^,"\'\\]|\"(?:[^"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')+?)\s*(?:,|$)', re.DOTALL)
RE_RULE = re.compile(r'\s*((?:[^;"\'\\]|\"(?:[^"\\]|\\.)*\"|\'(?:[^\'\\]|\\.)*\')+?)\s*(?:;|$)', re.DOTALL)
css = open(CSS_FILENAME).read()
print [(RE_SELECTOR.findall(i),
[re.split('\s*:\s*', k, 1)
for k in RE_RULE.findall(j)])
for i, j in RE_BLOCK.findall(css)]
Run Code Online (Sandbox Code Playgroud)
对于此示例 CSS:
body, p#abc, #cde, a img .fgh, * {
font-size: normal; background-color: white !important;
-webkit-box-shadow: none
}
#test[src~='{a\'bc}'], .tester {
-webkit-transition: opacity 0.35s linear;
background: white !important url("abc\"cd'{e}.jpg");
border-radius: 20px;
opacity: 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.6) 0px 0px 18px;
}
span {display: block;} .nothing{}
Run Code Online (Sandbox Code Playgroud)
...我们得到(为了清晰起见,间隔):
[(['body',
'p#abc',
'#cde',
'a img .fgh',
'*'],
[['font-size', 'normal'],
['background-color', 'white !important'],
['-webkit-box-shadow', 'none']]),
(["#test[src~='{a\\'bc}']",
'.tester'],
[['-webkit-transition', 'opacity 0.35s linear'],
['background', 'white !important url("abc\\"cd\'{e}.jpg")'],
['border-radius', '20px'],
['opacity', '0'],
['-webkit-box-shadow', 'rgba(0, 0, 0, 0.6) 0px 0px 18px']]),
(['span'],
[['display', 'block']]),
(['.nothing'],
[])]
Run Code Online (Sandbox Code Playgroud)
为读者提供的简单练习:编写一个正则表达式来删除 CSS 注释 ( /* ... */)。