【问题标题】:php preg_match not working as in other web applicationsphp preg_match 不像在其他 Web 应用程序中那样工作
【发布时间】:2016-10-19 09:57:18
【问题描述】:

尝试解析以下元素的值:

输入类型="隐藏" 名称="csrf_token" value="VUNht8fnmxmJXJIMassWW8SAwWKNJ3SC8POA4FtSqEKhG1rcoB3ZNqcPqa615tPsF_hzW0l4zDjSEHJYMz9Ogw==">

元素周围的区域如下所示:

          <input type="hidden" name="redirect" value="">
          <input type="hidden" name="invite_code" value="">
          <input type="hidden" name="invite" value="">
          <input type="hidden" name="country" value="">
          <input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg==">

          <div>

使用以下代码行:

preg_match("/csrf_token. value=.(.+==).>/", $result, $output_array);

$output_array 留空,其中http://www.phpliveregex.com/ 中的正则表达式是正确的。

我做错了什么?

【问题讨论】:

  • "/csrf_token. value=.(.+?==).&gt;/s"
  • @WiktorStribiżew 似乎不起作用,而且 /s 指定点匹配新行,我不希望这样。
  • 在这里工作,eval.in/590926。也许你的$result 不是你所期望的。同样使用解析器你可以拉出属性value 的值。
  • @chris85,听起来更好。

标签: php regex preg-match


【解决方案1】:

只是为了投入我的两分钱,一种使用DOMDocument的xpath查询方式:

<?php

$html = <<<EOF
          <input type="hidden" name="redirect" value="">
          <input type="hidden" name="invite_code" value="">
          <input type="hidden" name="invite" value="">
          <input type="hidden" name="country" value="">
          <input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg==">
          <div>
EOF;

$dom = new DOMDocument();
$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

$inputs = $xpath->query("//input[@name='csrf_token']/@value");
foreach ($inputs as $input) {
    echo $input->nodeValue;
    # 325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg==
}

// alternatively, if you're sure there's ALWAYS only ONE element, pick the first one
echo $xpath->query('//input[@name="csrf_token"]/@value')->item(0)->nodeValue;
?>

a demo on ideone.com

【讨论】:

    【解决方案2】:

    这是一个解析器版本:

    <?php
    $doc = new DOMDocument();
    $doc->loadHTML('<input type="hidden" name="csrf_token" value="VUNht8fnmxmJXJIMassWW8SAwWKNJ3SC8POA4FtSqEKhG1rcoB3ZNqcPqa615tPsF_hzW0l4zDjSEHJYMz9Ogw==">');
    foreach ($doc->getElementsByTagName('input') as $input) {
        if ($input->getAttribute('name') == 'csrf_token') {
            echo $input->getAttribute('value');
        }
    }
    

    演示:https://eval.in/590936

    【讨论】:

      【解决方案3】:

      使用 DOM 解析器通过 '//input[@name="csrf_token"]' XPath 获取您需要的所有值(即,获取包含 name 属性和 csrf_token 值的所有 input 标记)。

      查看example

      $html = <<<DATA
      <div>
      <input type="hidden" name="redirect" value="">
      <input type="hidden" name="invite_code" value="">
      <input type="hidden" name="invite" value="">
      <input type="hidden" name="country" value="">
      <input type="hidden" name="csrf_token" value="325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg==">
      </div>
      DATA;
      
      $dom = new DOMDocument('1.0', 'UTF-8');
      $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
      
      $xpath = new DOMXPath($dom);
      $inputs = $xpath->query('//input[@name="csrf_token"]');
      $res = array();
      foreach($inputs as $input) { 
         array_push($res, $input->getAttribute("value"));
      }
      print_r($res);
      

      输出:

      Array
      (
          [0] => 325fTt31vp42rbt90gNqBT923_Z04snI5tmhCOAhSzpmL2mr3NBAho1zp6bEirZrLdQna5Ocm6_iC3OYdbBqLg==
      )
      

      【讨论】:

      • 你可以直接访问它:echo $xpath-&gt;query('//input[@name="csrf_token"]/@value')-&gt;item(0)-&gt;nodeValue; 如果总是只有 一个 元素。
      • 如果还有更多呢?我只是展示了一种获取所有这些值的方法。当然,我们不知道实际的HTML,要求也不清楚。
      • 你知道答案,然后像你已经在做的那样循环结果是要走的路:)
      • DOMDocument 构造函数的第二个参数仅在您想从头开始创建新文档时才有用,此外,编码总是被文档中找到的编码(元标记,字节顺序标记,xml 声明)或使用默认值(大多数情况下为 utf-8)。无论如何,当您在构造函数中指定编码并在DOMDocument::load* 之后使用时,编码会被系统地覆盖。 (第一个参数也一样,如果你指定xml版本并在DOMDocument::loadHTML之后使用)
      【解决方案4】:

      正则表达式方式

      将文字空格替换为\s+:

      preg_match("/csrf_token.\s+value=.(.+==).>/", $result, $output_array);
      

      此外,您可能还想在这里改进一些其他的东西。一些建议:

      • 不要使用. 来匹配",而是使用['\"]?(不太通用,避免匹配csrf_token2 之类的随机事物)。
      • 使用[^='"]+=* 代替.+==(结果相同,但性能要好得多,并且匹配以1 或0 结尾的标记=s)。

      根据这些建议,您的代码将是:

      preg_match("/csrf_token['\"]?\s+value=['\"]?([^='\"]+=*)['\"]?>/", $result, $output_array);
      

      这是working demo

      更好的方法

      根本不要使用正则表达式解析 HTML。只需使用解析器。

      【讨论】:

      • 似乎也不起作用,将按照@chris85 所说的使用解析器。
      猜你喜欢
      • 2018-01-12
      • 2022-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多