从正则表达式捕获组中获取所有可能的匹配项

时间:2014-04-26 07:41:39

标签: php regex pcre

考虑以下正则表达式:

/\<form.+?((action|id|method|name)=(\"|\')(.*?)?(\"|\')).*?\>/i

它应该足以捕捉像<form>这样的基本内容,但也可以捕捉<form action="post.php" method="post" name="form1">之类的内容以及上述表达式中列出的这四种属性的其他各种组合。

我在基本/\<form.*?\>/i上选择此表达式的原因是因为我想从捕获组2和4(属性名称和属性值)中获取值。但是,当我在上面的复杂表单元素上运行此表达式时,它将仅返回 action post.php 。我想让它返回一系列匹配。

以下是一些示例代码:

<?php
    $string = '<form action="post.php" method="post" name="form1">';
    preg_match_all('/\<form.+?((action|id|method|name)=(\"|\')(.*?)?(\"|\')).*?\>/i', $string, $forms);
    print_r($forms);
?>

如果我在命令行中运行它以进行演示,请输出:

c:\Users\Aaron\Desktop>php test.php
Array
(
    [0] => Array
        (
            [0] => <form action="post.php" method="post" name="form1">
        )

    [1] => Array
        (
            [0] => action="post.php"
        )

    [2] => Array
        (
            [0] => action
        )

    [3] => Array
        (
            [0] => "
        )

    [4] => Array
        (
            [0] => post.php
        )

    [5] => Array
        (
            [0] => "
        )

)

我想要的输出是这样的:

c:\Users\Aaron\Desktop>php test.php
Array
(
    [0] => Array
        (
            [0] => <form action="post.php" method="post" name="form1">
            [1] => <form action="post.php" method="post" name="form1">
            [2] => <form action="post.php" method="post" name="form1">
        )

    [1] => Array
        (
            [0] => action="post.php"
            [1] => method="post"
            [2] => name="form1"
        )

    [2] => Array
        (
            [0] => action
            [1] => method
            [2] => name
        )

    [3] => Array
        (
            [0] => "
            [1] => "
            [2] => "
        )

    [4] => Array
        (
            [0] => post.php
            [1] => post
            [2] => form1
        )

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

)

我目前能够通过查找表单元素并多次运行表达式来解决此问题,因为我希望搜索多个属性。 Here is that code。但我不禁想到必须有一个更简单的方法吗?

所以问题是:我可以从捕获组返回所有匹配,而不仅仅是第一次匹配吗?

提前致谢。

2 个答案:

答案 0 :(得分:1)

我真诚的建议是不要使用正则表达式处理( HTML ),而只需使用DOM Parser。

代码..

<?php
$string = '<form action="post.php" method="post" name="form1">';
$dom = new DOMDocument;
$dom->loadHTML($string);
foreach ($dom->getElementsByTagName('form') as $ftag) {
    if ($ftag->hasAttributes()) {
        foreach ($ftag->attributes as $attribute) {
            $attrib[$attribute->nodeName] = $attribute->nodeValue;
        }
    }
}
print_r($attrib);

输出:

Array
(
    [action] => post.php
    [method] => post
    [name] => form1
)

答案 1 :(得分:1)

你必须先找到一个表单元素。

<?php
 $string = '<form action="post.php" method="post" name="form1">';
 preg_match_all('/\<form+?\>/i', $string, $forms);

然后在内部应用正则表达式:

 foreach($form in $forms){
  preg_match_all('/((action|id|method|name)=(("[^"]*")|(\'[^\']*\'))/i',$form[0],$attrs);
 }
 $form = array_merge($form,$attrs);
 print_r($forms);
?>

我没有设备可以尝试,如果它的工作。希望它确实:)

相关问题