正则表达式替换CSS中的css值

时间:2011-01-15 18:57:59

标签: php css regex

嘿。 我正在尝试使用PHP解析CSS文件。

我正在尝试运行这个表达式:

"/(". $selector . "\\s*{[\\w\\s:\\-;()#]*)(" . $property . ":)([^;}]+)(}?)/Ui"

这个正则表达式应该固定选择器中的特定属性,并允许我更改它的值/删除它。

理性:

  1. 匹配选择器及其在属性
  2. 之前的文本
  3. 匹配属性名称
  4. 匹配属性值
  5. 如果值以}符号结尾 - 也可以抓住它
  6. 破碎的位是#3 - 由于某些未知的原因,当我通过preg_match运行时,值组(#3)仅捕获第一个char。

    例如,运行此表达式:

    preg_replace("/(h1\s*{[\w\s:\-;()#]*)(font-size:)(([^;}])+)(}?)/Ui","$1 $4",$css);
    

    (找到h1选择器的font-size属性,并删除属性和值)

    关于这个css小组:

    h1{
        background:#fff;
        font-size:10px;
        text-align:underline;
        color:#abc;
    }
    

    我明白了:

    h1{
        background:#fff;
        /* note that although the property was matched and removed,
           the value only matched the 1st char: 1 */ 
        0px; 
        text-align:underline;
        color:#abc;
    }
    

    我试图通过一些测试工具检查表达式并且它工作正常,所以我猜这是一个preg *特定问题。

    任何想法我做错了什么?

4 个答案:

答案 0 :(得分:1)

仅使用regexp解析CSS是受虐狂。

您可以在此CSS object model specification中找到有关如何解析CSS的一些信息。抱歉,我只能找到编辑的草稿,其他网址似乎已被破坏。

答案 1 :(得分:0)

不要重新组合第3个括号,请尝试:

preg_replace("/(h1\s*{[\w\s:\-;()#]*)(font-size\s*:)([^;}]+)(}?)/Ui","$1 $4",$css);

另外,我在属性之后添加了\ s *,以允许它捕获像

这样的东西
font-size : 10px

答案 2 :(得分:0)

(([^;}])+)(}?)实际上只匹配一个字符(带有修饰符U)。

您必须使用以下内容:([^;}]+)(;|})

另外,逃避花括号也不错。

完整的RegEx:

preg_replace('/('.$selector.'\s*\{[\w\s:\-;\(\)#]*)('.$property.'\s*:)([^;\}]+)(;|\})/Ui', '$1 $4', $css);

答案 3 :(得分:0)

你用“ungreedy”修饰符'/ U'折磨自己,我不会用它。
真正的问题是你正在为“财产:价值”做出规定,结果是';'或'}'

所以,它可以是[;}],也就是你的最后一个分隔符。实际上没有简单的方法来实现,同时保留格式,我稍微重写你的正则表达式。 认为php确实是Perl兼容的正则表达式,因此重新排列并将最后一部分篡改为合理的工作模型。它不适合胆小的人。

修饰符是Perl的/ xi代表扩展和不区分大小写 不要在这上面使用php的/ U修饰符!现在只有2个捕获组,1& 2。

正则表达式没有引用变量:

/((?:$selector)\s*\{[\w\s:;()#-]*?)\s*(?:$property)\s*:(?:(?!\s*\})[^;])+(?:(?=;);[^\S\n]*)?(\s*\}?)/i;

正则表达式是一个字符串:

'/((?:' . $selector . ')\s*\{[\w\s:;()#-]*?)\s*(?:' . $property. ')\s*:(?:(?!\s*\})[^;])+(?:(?=;);[^\S\n]*)?(\s*\}?)/xi;'

Perl中的测试用例:

use strict;
use warnings;

my ($selector, $property) = ( 'h1 | h2', 'font-size' );

my $sample = 
'
h1{
    background:#fff;
    font-size:10px;
    text-align:underline;
    color:#abc;
}
h2{
    text-align:strikethrough;
    background:#fefe;
    color:#dbd;
    font-size:10px
} ';

my $rx = qr/
  (                      # group 1
      (?:$selector)
      \s*
      \{
         [\w\s:;()#-]*?
  )
         \s* (?:$property) \s*: (?: (?!\s*\}) [^;] )+
         (?:
             (?=;) ;[^\S\n]*
         )?
  (                      # group 2
      \s*
      \}?
  )
/xi;

print $rx,"\n\n";

$sample =~ s/$rx/$1$2/g;

print $sample,"\n";

输出:

(?ix-sm:
  (                      # group 1
      (?:h1 | h2)
      \s*
      \{
         [\w\s:;()#-]*?
  )
         \s* (?:font-size) \s*: (?: (?!\s*\}) [^;] )+
         (?:
             (?=;) ;[^\S\n]*
         )?
  (                      # group 2
      \s*
       \}?
  )
)

h1{
    background:#fff;
    text-align:underline;
    color:#abc;
}
h2{
    text-align:strikethrough;
    background:#fefe;
    color:#dbd;
}
/((?:h1 | h2)\s*\{[\w\s:;()#-]*?)\s*(?:font-size)\s*:(?:(?!\s*\})[^;])+(?:(?=;);[^\S\n]*)?(\s*\}?)/xi;