我正在创建一个CSS编辑器,我正在尝试创建一个可以从CSS文档中获取数据的正则表达式.如果我有一个属性但是我不能让它适用于所有属性,这个正则表达式是有效的.我在PHP中使用preg/perl语法.
(?[A-Za-z]+[\s]*)[\s]*{[\s]*((? [A-Za-z0-9-_]+)[\s]*:[\s]*(? [A-Za-z0-9#, ]+);[\s]*)*[\s]*}
body { background: #f00; font: 12px Arial; }
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 ) ) )
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 ) )
在此先感谢您的帮助 - 整个下午这让我感到困惑!
对于单个正则表达式来说,这似乎太复杂了.好吧,我确信通过正确的扩展,高级用户可以创建正确的正则表达式.但是,你需要一个更高级的用户来调试它.
相反,我建议使用正则表达式来拉出碎片,然后分别标记每个碎片.例如,
/([^{])\s*\{\s*([^}]*?)\s*}/
然后,您最终将选择器和属性放在单独的字段中,然后将它们分开.(即使是选择器也很有趣.)请注意,如果}可以出现在引号或其他内容中,即使这样也会很麻烦.你可以再次为了避免这种情况而卷入其中,但是在这里完全避免正则表达式可能更好,并且通过一次解析一个字段来处理它,可能是通过使用递归下降解析器或yacc/bison或者随你.
您试图从数据中提取结构,而不仅仅是单个值.正则表达式可能会痛苦地延伸到完成这项工作,但你真的进入了解析器领域,应该拔出大枪,即解析器.
我从未使用过PHP解析器生成工具,但是在对文档进行轻微扫描后它们看起来还不错.查看LexerGenerator和ParserGenerator.LexerGenerator将采用一堆正则表达式来描述语言中的不同类型的标记(在本例中为CSS),并吐出一些识别单个标记的代码.ParserGenerator将采用语法,描述语言中的内容由其他内容构成,并吐出解析器,代码需要一堆令牌并返回语法树(您所追求的数据结构).
不要使用自己的正则表达式来解析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);
..输出以下内容:
Array ( [body] => Array ( [background] => #f00 [font] => 12px arial ) )
解析器非常简单,因此应该很容易弄清楚它正在做什么.哦,我不得不删除读取的行if($this->html) {$this->Add("VAR", "");}
(它似乎是一个调试的东西)
我已经在这里镜像了脚本,并进行了上述更改
我正在使用下面的正则表达式,它几乎可以工作......当然这个问题现在已经过时了,我看到你已经放弃了你的努力......但是万一其他人遇到它:
(?(?:(?:[^,{]+),?)*?)\{(?:(? [^}:]+):?(? [^};]+);?)*?\}
(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]; } } }
给你这个:
Array ( [body] => Array ( [background] => #f00 [font] => 12px arial ) )