Php 使用正则表达式提取表单字段

Php 使用正则表达式提取表单字段,php,html,regex,forms,Php,Html,Regex,Forms,我正在寻找一种方法,从给定特定URL和表单名称的页面获取所有表单输入和相应的值 function GetForm($url, $name) { return array ( 'field_name_1' => 'value_1', 'field_name_2' => 'value_2', 'select_field_name' => array('option_1', 'option_2', 'option_3')

我正在寻找一种方法,从给定特定URL和表单名称的页面获取所有表单输入和相应的值

function GetForm($url, $name)
{
    return array
    (
        'field_name_1' => 'value_1',
        'field_name_2' => 'value_2',
        'select_field_name' => array('option_1', 'option_2', 'option_3'),
    );
}

GetForm('http://www.google.com/', 'f');
有人能为我提供必要的正则表达式来实现这一点吗

编辑:我知道查询DOM要可靠得多,但是我要寻找的是一个网站不可知的解决方案,它允许我获取给定表单的所有字段。我认为在不首先知道文档节点的情况下,DOM不可能做到这一点,我错了吗

我不需要防弹的解决方案,只需要在标准网页上工作的东西,我为表单标签提供了以下正则表达式

'~<form.*?name=[\'"]?' . $name . '[\'"]?.*?>(.+?)</form>~is'

使用正则表达式解析HTML可能不是最好的方法

您可以看看,这将允许您使用DOM方法(例如,如果您知道这些方法,还可以使用XPath查询)处理HTML文档

您可能还想看看和,顺便说一句,如果您可以在应用程序中使用Zend Framework的某些部分,那么这两种方法非常好。
例如,在进行函数测试时,它们用于从HTML页面获取数据,并且工作得非常好;-)

首先,这可能看起来更难。。。但是,考虑到一些HTML页面的混乱,这可能是一个更明智的想法


在评论和OP编辑之后进行编辑

以下是关于输入标记的一些想法,从“简单”开始:

  • 它可以跨越几条线传播
  • 它可以有许多属性
  • 如果您只对名称和值感兴趣,那么您必须处理这样一个事实,即这两个值可以按任何可能的顺序排列
  • 属性的值周围可以有双引号、单引号,甚至没有任何内容
  • 标记/属性可以是小写或大写
  • 标记并不总是必须关闭
嗯,其中一些点不是有效的HTML;但在大多数通用的web浏览器中仍然可以工作,因此必须将它们考虑在内

只有这些观点,我才不想成为编写正则表达式的人^^
但我想可能还有其他我没有想到的困难


另一方面,您有DOM和xpath。。。要获取输入name=“q”(示例为)的值,需要处理如下事项:

$url = 'http://www.google.fr/search?q=test&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeList = $xpath->query('//input[@name="q"]');
    if ($nodeList->length > 0) {
        for ($i=0 ; $i<$nodeList->length ; $i++) {
            $node = $nodeList->item($i);
            var_dump($node->getAttribute('value'));
        }
    }

} else {
    // too bad...
}
(我选中:页面上有两个输入name=“q”)

我知道这页的结构吗?绝对不是;-)
我只知道我/你/我们需要名为q;-)的输入标记

这就是我们得到的;-)


编辑2:选择和选项有点有趣:

好吧,只是为了好玩,下面是我为select and option设计的:

$url = 'http://www.google.fr/language_tools?hl=fr';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeListSelects = $xpath->query('//select');
    if ($nodeListSelects->length > 0) {
        for ($i=0 ; $i<$nodeListSelects->length ; $i++) {
            $nodeSelect = $nodeListSelects->item($i);
            $name = $nodeSelect->getAttribute('name');
            $nodeListOptions = $xpath->query('option[@selected="selected"]', $nodeSelect);  // We want options that are inside the current select
            if ($nodeListOptions->length > 0) {
                for ($j=0 ; $j<$nodeListOptions->length ; $j++) {
                    $nodeOption = $nodeListOptions->item($j);
                    $value = $nodeOption->getAttribute('value');
                    var_dump("name='$name' => value='$value'");
                }
            }
        }
    }
} else {
    // too bad...
}
这正是我所期望的


有什么解释吗

首先,我获取页面的所有select标记,并将它们的名称保存在内存中。
然后,对于其中的每一个,我都会得到作为其后代的所选选项标记(顺便说一句,始终只有一个)。
在这里,我有价值

比上一个例子要复杂一点。。。但我相信还是比正则表达式简单得多。。。我花了大概10分钟,不是更多。。。我仍然没有勇气(疯狂?)开始思考某种能够做到这一点的变异正则表达式:-D

哦,作为旁注:我仍然不知道HTML文档的结构是什么样子的:我甚至没有看一眼它的源代码^^


我希望这能帮上忙。。。
谁知道呢,也许我会说服你,在解析HTML时,正则表达式不是一个好主意。。。也许吧<强>;-)


仍然:玩得开心

使用正则表达式解析HTML可能不是最好的方法

您可以看看,这将允许您使用DOM方法(例如,如果您知道这些方法,还可以使用XPath查询)处理HTML文档

您可能还想看看和,顺便说一句,如果您可以在应用程序中使用Zend Framework的某些部分,那么这两种方法非常好。
例如,在进行函数测试时,它们用于从HTML页面获取数据,并且工作得非常好;-)

首先,这可能看起来更难。。。但是,考虑到一些HTML页面的混乱,这可能是一个更明智的想法


在评论和OP编辑之后进行编辑

以下是关于输入标记的一些想法,从“简单”开始:

  • 它可以跨越几条线传播
  • 它可以有许多属性
  • 如果您只对名称和值感兴趣,那么您必须处理这样一个事实,即这两个值可以按任何可能的顺序排列
  • 属性的值周围可以有双引号、单引号,甚至没有任何内容
  • 标记/属性可以是小写或大写
  • 标记并不总是必须关闭
嗯,其中一些点不是有效的HTML;但在大多数通用的web浏览器中仍然可以工作,因此必须将它们考虑在内

只有这些观点,我才不想成为编写正则表达式的人^^
但我想可能还有其他我没有想到的困难


另一方面,您有DOM和xpath。。。要获取输入name=“q”(示例为)的值,需要处理如下事项:

$url = 'http://www.google.fr/search?q=test&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeList = $xpath->query('//input[@name="q"]');
    if ($nodeList->length > 0) {
        for ($i=0 ; $i<$nodeList->length ; $i++) {
            $node = $nodeList->item($i);
            var_dump($node->getAttribute('value'));
        }
    }

} else {
    // too bad...
}
(我选中:页面上有两个输入name=“q”)

我知道这页的结构吗?绝对不是;-)
我只知道我/你/我们需要名为q;-)的输入标记

这就是我们得到的;-)


编辑2:选择和选项有点有趣:

好吧,只是为了好玩,下面是我为select and option设计的:

$url = 'http://www.google.fr/language_tools?hl=fr';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeListSelects = $xpath->query('//select');
    if ($nodeListSelects->length > 0) {
        for ($i=0 ; $i<$nodeListSelects->length ; $i++) {
            $nodeSelect = $nodeListSelects->item($i);
            $name = $nodeSelect->getAttribute('name');
            $nodeListOptions = $xpath->query('option[@selected="selected"]', $nodeSelect);  // We want options that are inside the current select
            if ($nodeListOptions->length > 0) {
                for ($j=0 ; $j<$nodeListOptions->length ; $j++) {
                    $nodeOption = $nodeListOptions->item($j);
                    $value = $nodeOption->getAttribute('value');
                    var_dump("name='$name' => value='$value'");
                }
            }
        }
    }
} else {
    // too bad...
}
这正是我所期望的


有什么解释吗

首先,我获取页面的所有select标记,并将它们的名称保存在内存中。
然后,对于其中的每一个,我都会得到所选的选项标签,这些标签是它的下降部分