dtd793353 2013-03-19 04:41
浏览 47
已采纳

php正则表达式匹配shorttags

This is close, but is failing to match successive "attributes":

$string = "single attribute [include file=\"bob.txt\"] multiple attributes [another prop=\"val\" attr=\"one\"] no attributes [tag] etc";
preg_match_all('/\[((\w+)((\s(\w+)="([^"]+)"))*)\]/', $string, $matches, PREG_SET_ORDER);
print '<pre>' . print_r($matches, TRUE) . '</pre>';

Gives back the following:

Array
(
    [0] => Array
        (
            [0] => [include file="bob.txt"]
            [1] => include file="bob.txt"
            [2] => include
            [3] =>  file="bob.txt"
            [4] =>  file="bob.txt"
            [5] => file
            [6] => bob.txt
        )

    [1] => Array
        (
            [0] => [another prop="val" attr="one"]
            [1] => another prop="val" attr="one"
            [2] => another
            [3] =>  attr="one"
            [4] =>  attr="one"
            [5] => attr
            [6] => one
        )

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

)

Where [2] is the tag name, [5] is the attribute name and [6] is the attribute value.

The failure is on the second node - it catches attr="one" but not prop="val"

TYIA.

(this is only meant for limited, controlled use - not broad distribution - so I don't need to worry about single quotes or escaped double quotes)

  • 写回答

1条回答 默认 最新

  • douhun8647 2013-03-19 04:49
    关注

    Unfortunately there is no way to repeat capture groups like that. Personally, I would use preg_match to match the tags themselves (i.e. remove all the extra parentheses inside the regex), then foreach match you can then extract the attributes. Something like this:

    $string = "single attribute [include file=\"bob.txt\"] multiple attributes [another prop=\"val\" attr=\"one\"] no attributes [tag] etc";
    preg_match_all('/\[\w+(?:\s\w+="[^"]+")*\]/', $string, $matches);
    foreach($matches[0] as $m) {
        preg_match('/^\w+/', $m, $tagname); $tagname = $tagname[0];
        preg_match_all('/\s(\w+)="([^"]+)"/', $m, $attrs, PREG_SET_ORDER);
        // do something with $tagname and $attrs
    }
    

    Note that if you intend to replace the tag with some content, you should use preg_replace_callback like so:

    $string = "single attribute [include file=\"bob.txt\"] multiple attributes [another prop=\"val\" attr=\"one\"] no attributes [tag] etc";
    $output = preg_replace_callback('/\[\w+(?:\s\w+="[^"]+")*\]/', $string, function($match) {
        preg_match('/^\w+/', $m, $tagname); $tagname = $tagname[0];
        preg_match_all('/\s(\w+)="([^"]+)"/', $m, $attrs, PREG_SET_ORDER);
        $result = // do something with $tagname and $attrs
        return $result;
    });
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?