【问题标题】:Regex Expression works fine in online testers, but not working on my page正则表达式在在线测试人员中工作正常,但在我的页面上不起作用
【发布时间】:2014-07-07 06:47:27
【问题描述】:

所以我正在读取一个 css 文件,我想从中获取一些数据。我目前将数据完全缩减为:

font-family: "Verdana";
font-size: 14px;
color: #000000;

为了纯粹获取我需要的数据(即 Verdana、14 和 #000000),我创建了以下 PHP 代码:

foreach($tmp as $tmpstr){
        if(strpos($tmpstr, "font-family")){
            $tmpres = array();
            preg_match('/\"(.*?)\"/', $tmpstr, $tmpres);
            $returnData["website"]["font-family"] = $tmpres[1];
        } else if(strpos($tmpstr, "font-size")){
            $tmpres2 = array();
            preg_match_all('/\:\s(.*?)px\;/', $tmpstr, $tmpres2);
            $returnData["website"]["font-size"] = $tmpres2[1];
        } else if(strpos($tmpstr, "color")){
            $tmpres3 = array();
            preg_match_all('/color\:\s(.*?)\;/', $tmpstr, $tmpres3);
            $returnData["website"]["font-color"] = $tmpres3[1];
        }
    }

我知道它还没有优化,但原因是它不起作用。第一个表达式 '/\"(.*?)\"/' 获得 Verdana 工作正常,但其他两个('/\:\s(.*?)px\;/' 获得字体大小,/color\:\s(.*?)\;/ 获得字体颜色)没有,而在在线测试仪中测试它们似乎确实有效.谁能告诉我我做错了什么?

谢谢!

【问题讨论】:

  • 其他2个不运行,因为if\ele结构,再考虑你的逻辑
  • 第一个有效,可能不是问题,但请注意strpos() 可以返回0,因此您需要将其与false 进行比较,例如:if(strpos($tmpstr, "font-size") !== false)
  • 使用 preg 匹配所有,它是一个只有 css 样式的文件吗?您可以将整个文件提取到一个数组中,预匹配所有文件,然后在可用的数组结构中进行尽可能多的处理。
  • 我会将您的 \s 更新为 \s* (0 或更多)它完全有效的 css 以这种方式( font-family:"Verdana", font-family: "Verdana"
  • @jeroen 我完全忘记了!我习惯了 Java 的“StartsWith()”函数,它只返回 true 或 false,即使函数名告诉我它会返回一个数字,但我没想到它可以返回 0。谢谢指出这一点!

标签: php css regex


【解决方案1】:

检查这个例子

$tmp = array(
    'font-family: "Verdana";',
    'font-size: 14px;',
    'color: #000000;'
);

foreach($tmp as $tmpstr)
{
    if (false !== strpos($tmpstr, "font-family"))
    {
        preg_match('/:[ ]*"(.*)"/', $tmpstr, $tmpres);
        echo $tmpres[1];
    } 
    else if (false !== strpos($tmpstr, "font-size"))
    {
        preg_match('/:[ ]*(\d*)px/', $tmpstr, $tmpres2);
        echo $tmpres2[1];
    } 
    else if (false !== strpos($tmpstr, "color"))
    {
        preg_match('/:[ ]*(.*);/', $tmpstr, $tmpres3);
        echo $tmpres3[1];
    }

    echo '<br />';
}

结果:

Verdana
14
#000000

希望此解决方案有所帮助!

【讨论】:

    【解决方案2】:

    试试这个:

    $css = 'font-family: "Verdana";
    font-size: 14px;
    color: #000000;'
    
    
    preg_match_all('(?P<key>.+?)\:\s*(?P<value>.+?)\;', $css, $result, PREG_SET_ORDER);
    

    输出:

    Array
    (
        [0] => Array
            (
                [0] => font-family: "Verdana";
                [key] => font-family
                [1] => font-family
                [value] => "Verdana"
                [2] => "Verdana"
            )
    
        [1] => Array
            (
                [0] => font-size: 14px;
                [key] => font-size
                [1] => font-size
                [value] => 14px
                [2] => 14px
            )
    
        [2] => Array
            (
                [0] => color: #000000;
                [key] => color
                [1] => color
                [value] => #000000
                [2] => #000000
            )
    
    )
    

    那么做一个foreach循环来清理输出应该是一件小事:

    $data = array()
    foreach($result as $r){
      $data[$r['key']] = $r['value'];
    }
    

    输出:

    array
    (
         [font-family] => "Verdana",
         [font-size] => 14px,
         [color] => #000000
    )
    

    作为旁注,您可以将其扩展到整个文件:

    /(?P<selectors>.*?)\s*\{|(?P<key>.+?)\:\s*(?P<value>.+?)\;/
    
    
    
     #id, and some class
        {
        font-family: "Verdana";
        font-size: 14px;
        color: #000000;
        }
    
       #id2, and some class1
        { ..... and so on.
    

    输出:

    array
    (
        [0] => Array
            (
                [0] => #id, and some class
    {
                [selectors] => #id, and some class ///you may want to post process this and split on comma etc.
                [1] => #id, and some class
            )
    
    
    
           [1] => Array
                (
                    [0] => font-family: "Verdana";
                    [selectors] => 
                    [1] => 
                    [key] => font-family
                    [2] => font-family
                    [value] => "Verdana"
                    [3] => "Verdana"
                )
    
            [2] => Array
                (
                    [0] => font-size: 14px;
                    [selectors] => 
                    [1] => 
                    [key] => font-size
                    [2] => font-size
                    [value] => 14px
                    [3] => 14px
                )
    
            [3] => Array
                (
                    [0] => color: #000000;
                    [selectors] => 
                    [1] => 
                    [key] => color
                    [2] => color
                    [value] => #000000
                    [3] => #000000
                 )
             [4] => Array
                (
                    [0] => #id2, and some class1
        {
                    [selectors] => #id2, and some class1
                    [1] => #id2, and some class1
                ) .....
    

    更新,抱歉,您要检查是否为空(以前我有 isset ),因为我看到每个都设置了 $r['selectors'] 。然后,您可以通过其选择器对每个样式块进行子数组,并解析为您的 hart 内容。你明白了,但如果你需要这方面的帮助,只需询问(在这种情况下删除 PRET_SET_ORDER 可能会更好)......

    这将是我建议的 css 文件的结束结构..

    array(
    selector => array( color => 'bla', font => blabla )
    selector2 => array( ..... 
    )
    

    我认为 preg_match_all 没有得到它需要的关注,它对这种事情真的很有用,如果你不熟悉它,请查看 php doc http://www.php.net/manual/en/function.preg-match-all.php

    【讨论】:

    • 这确实可以很好地完成工作,但它(目前)比我想要的要多。如果我决定使用整个 css 文件,我可以使用这个 =)
    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多