【问题标题】:Parsing attributes in PHP using regular expressions使用正则表达式解析 PHP 中的属性
【发布时间】:2011-12-22 13:44:11
【问题描述】:

考虑到我有字符串,

$string = 'tag2 display="users" limit="5"';

使用preg_match_all函数,我需要得到输出

必需的 o/p

Array
(
    [0] => Array
        (
            [0] => tag2
            [1] => tag2
            [2] => 
        )

    [1] => Array
        (
            [0] => display="users"
            [1] => display
            [2] => users
        )

    [2] => Array
        (
            [0] => limit="5"
            [1] => limit
            [2] => 5
        )

)

我尝试使用此模式'/([^=\s]+)="([^"]+)"/',但它无法识别没有值的参数(在本例中为 tag2)而是给出了输出

我得到了什么

Array
(
    [0] => Array
        (
            [0] => display="users"
            [1] => display
            [2] => users
        )

    [1] => Array
        (
            [0] => limit="5"
            [1] => limit
            [2] => 5
        )

)

获得所需输出的模式是什么?

编辑 1: 我还需要获取未用引号括起来的属性,例如:attr=val。很抱歉之前没有提及。

【问题讨论】:

    标签: php regex parsing attributes


    【解决方案1】:

    试试这个:

    <?php
    
        $string = 'tag2 display="users" limit="5"';
        preg_match_all('/([^=\s]+)(="([^"]+)")?/', $string, $res);
    
        foreach ($res[0] as $r => $v) {
            $o[] = array($res[0][$r], $res[1][$r], $res[3][$r]);
        }
    
        print_r($o);
    
    ?>
    

    它输出我:

    Array
    (
        [0] => Array
            (
                [0] => tag2
                [1] => tag2
                [2] => 
            )
    
        [1] => Array
            (
                [0] => display="users"
                [1] => display
                [2] => users
            )
    
        [2] => Array
            (
                [0] => limit="5"
                [1] => limit
                [2] => 5
            )
    
    )
    

    【讨论】:

    • 有点类似......如果我得到所需的o / p会很好,因为我的其他功能取决于确切所需的数组..
    • 我做了一些更改以适应您定义的输出。
    • 很好的答案,谢谢...但是当我尝试不带引号时,它不起作用...即param=val 抱歉,我应该在此之前告诉...
    • 没问题,用这个正则表达式打补丁:/([^=\s]+)(="?([^"]+)"?)?/
    • 我尝试了 hakre 的模式/([^=\s]+)(?:="([^"]+)")?/,结果非常好。但如果没有引号,它就无法工作......解决办法是什么......我相信这很容易......
    【解决方案2】:

    我认为不可能通过一个电话给您所需的内容,但这非常接近:

    $string = 'tag2 display="users" limit=5';
    preg_match_all('/([^=\s]+)(?:="?([^"]+)"?|())?/', $string, $res, PREG_SET_ORDER);
    print_r($res);
    

    输出:

    Array
    (
        [0] => Array
            (
                [0] => tag2
                [1] => tag2
                [2] => 
                [3] => 
            )
    
        [1] => Array
            (
                [0] => display="users"
                [1] => display
                [2] => users
            )
    
        [2] => Array
            (
                [0] => limit=5
                [1] => limit
                [2] => 5
            )
    
    )
    

    如您所见,第一个元素没有价值,我试图解决这个问题并提供一个空匹配。所以这会构建您要求的数组,但在空属性上有一个额外的条目。

    但重点是preg_match_allPREG_SET_ORDER 标志。也许你已经可以接受这个输出了。

    【讨论】:

    • 如何调整模式以获取不带引号的参数?
    • @AakashChakravarthy:我为这些添加了一个调整。但是,我认为如果您想要一些真正安全的东西,这需要再次更新。
    • 还有一个问题,当参数值为空时,输出不正确... 会有什么调整?
    • 没错,子索引 2 是一个空字符串。唯一不同的是有一个额外的子索引 3。这真的有问题吗?如果您需要在值中包含转义字符,请留下注释,这个答案显示了一些技巧:@AakashChakravarthy:我为这些添加了一个调整。但是,我认为如果您想要一些真正安全的东西,这需要再次更新,请参阅stackoverflow.com/questions/6243778/…
    • 不,这不是问题......当tag param="" -----> 参数值为空时,在这种情况下我得到一个不同的o / p。我尝试调整(?:="?([^"]+)"?|()) 部分,但它是徒劳的......你有什么想法吗?
    【解决方案3】:

    也许您对解析各种属性样式的this litte snippet 感兴趣。 &lt;div class="hello" id=foobar style='display:none'&gt; 是有效的 html(5),不漂亮,我知道……

    <?php
    $string = '<tag2 display="users" limit="5">';
    
    $attributes = array();
    $pattern = "/\s+(?<name>[a-z0-9-]+)=(((?<quotes>['\"])(?<value>.*?)\k<quotes>)|(?<value2>[^'\" ]+))/i";
    preg_match_all($pattern, $source, $matches, PREG_SET_ORDER);
    foreach ($matches as $match) {
      $attributes[$match['name']] = $match['value'] ?: $match['value2'];
    }
    
    var_dump($attributes);
    

    会给你

    $attributes = array(
      'display' => 'users',
      'limit' => '5',
    );
    

    【讨论】:

      猜你喜欢
      • 2010-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-03
      • 2013-03-16
      • 2010-11-25
      相关资源
      最近更新 更多