Ros*_*oss 12 css php regex css-parsing
我正在创建一个CSS编辑器,我正在尝试创建一个可以从CSS文档中获取数据的正则表达式.如果我有一个属性但是我不能让它适用于所有属性,这个正则表达式是有效的.我在PHP中使用preg/perl语法.
(?<selector>[A-Za-z]+[\s]*)[\s]*{[\s]*((?<properties>[A-Za-z0-9-_]+)[\s]*:[\s]*(?<values>[A-Za-z0-9#, ]+);[\s]*)*[\s]*}
Run Code Online (Sandbox Code Playgroud)
body { background: #f00; font: 12px Arial; }
Run Code Online (Sandbox Code Playgroud)
Array(
[0] => Array(
[0] => body { background: #f00; font: 12px Arial; }
[selector] => Array(
[0] => body
)
[1] => Array(
[0] => body
)
[2] => font: 12px Arial;
[properties] => Array(
[0] => font
)
[3] => Array(
[0] => font
)
[values] => Array(
[0] => 12px Arial
[1] => background: #f00
)
[4] => Array(
[0] => 12px Arial
[1] => background: #f00
)
)
)
Run Code Online (Sandbox Code Playgroud)
Array(
[0] => Array
(
[0] => body { background: #f00; font: 12px Arial; }
[selector] => body
[1] => body
[2] => font: 12px Arial;
[properties] => font
[3] => font
[values] => 12px Arial
[4] => 12px Arial
)
)
Run Code Online (Sandbox Code Playgroud)
在此先感谢您的帮助 - 整个下午这让我感到困惑!
Tan*_*lus 19
对于单个正则表达式来说,这似乎太复杂了.好吧,我确信通过正确的扩展,高级用户可以创建正确的正则表达式.但是,你需要一个更高级的用户来调试它.
相反,我建议使用正则表达式来拉出碎片,然后分别标记每个碎片.例如,
/([^{])\s*\{\s*([^}]*?)\s*}/
Run Code Online (Sandbox Code Playgroud)
然后,您最终将选择器和属性放在单独的字段中,然后将它们分开.(即使是选择器也很有趣.)请注意,如果}可以出现在引号或其他内容中,即使这样也会很麻烦.你可以再次为了避免这种情况而卷入其中,但是在这里完全避免正则表达式可能更好,并且通过一次解析一个字段来处理它,可能是通过使用递归下降解析器或yacc/bison或者随你.
And*_*isi 10
您试图从数据中提取结构,而不仅仅是单个值.正则表达式可能会痛苦地延伸到完成这项工作,但你真的进入了解析器领域,应该拔出大枪,即解析器.
我从未使用过PHP解析器生成工具,但是在对文档进行轻微扫描后它们看起来还不错.查看LexerGenerator和ParserGenerator.LexerGenerator将采用一堆正则表达式来描述语言中的不同类型的标记(在本例中为CSS),并吐出一些识别单个标记的代码.ParserGenerator将采用语法,描述语言中的内容由其他内容构成,并吐出解析器,代码需要一堆令牌并返回语法树(您所追求的数据结构).
小智 10
不要使用自己的正则表达式来解析CSS.为什么在代码等待你,准备使用和(希望)没有错误的时候重新发明轮子?
有两个通常可用的类可以为您解析CSS:
pear.php.net上的HTML_CSS PEAR包
和
PHPCLasses的CSS Parser课程:
http://www.phpclasses.org/browse/package/1289.html
我建议不要使用正则表达式来解析CSS - 特别是在单个正则表达式中!
如果您坚持在正则表达式中进行解析,请将其拆分为合理的部分 - 使用一个正则表达式来拆分所有body{..}块,然后使用另一个正则表达式来解析color:rgb(1,2,3);属性.
如果您实际上正在尝试编写"有用"的东西(而不是尝试学习正则表达式),请寻找预先编写的CSS解析器.
我发现这个cssparser.php看起来效果很好:
$cssp = new cssparser;
$cssp -> ParseStr("body { background: #f00;font: 12px Arial; }");
print_r($cssp->css);
Run Code Online (Sandbox Code Playgroud)
..输出以下内容:
Array
(
[body] => Array
(
[background] => #f00
[font] => 12px arial
)
)
Run Code Online (Sandbox Code Playgroud)
解析器非常简单,因此应该很容易弄清楚它正在做什么.哦,我不得不删除读取的行if($this->html) {$this->Add("VAR", "");}(它似乎是一个调试的东西)
我已经在这里镜像了脚本,并进行了上述更改
我正在使用下面的正则表达式,它几乎可以工作......当然这个问题现在已经过时了,我看到你已经放弃了你的努力......但是万一其他人遇到它:
(?<selector>(?:(?:[^,{]+),?)*?)\{(?:(?<name>[^}:]+):?(?<value>[^};]+);?)*?\}
Run Code Online (Sandbox Code Playgroud)
(hafta 首先从CSS中删除所有/*注释*/以保证安全)
我写了一段很容易解析CSS的代码.所有你需要做的就是做几次爆炸...... $ css变量是CSS的一个字符串.所有你需要做的就是做print_r($css)一个很好的CSS数组,完全解析.
$css_array = array(); // master array to hold all values
$element = explode('}', $css);
foreach ($element as $element) {
// get the name of the CSS element
$a_name = explode('{', $element);
$name = $a_name[0];
// get all the key:value pair styles
$a_styles = explode(';', $element);
// remove element name from first property element
$a_styles[0] = str_replace($name . '{', '', $a_styles[0]);
// loop through each style and split apart the key from the value
$count = count($a_styles);
for ($a=0;$a<$count;$a++) {
if ($a_styles[$a] != '') {
$a_key_value = explode(':', $a_styles[$a]);
// build the master css array
$css_array[$name][$a_key_value[0]] = $a_key_value[1];
}
}
}
Run Code Online (Sandbox Code Playgroud)
给你这个:
Array
(
[body] => Array
(
[background] => #f00
[font] => 12px arial
)
)
Run Code Online (Sandbox Code Playgroud)