dongping2023 2018-05-07 23:24
浏览 144
已采纳

使用正则表达式和php从html中提取javascript对象

I am trying to extract a specific JavaScript object from a page containing the usual HTML markup.

I have tried to use regex but i don't seem to be able to get it to parse the HTML correctly when the HTML contains a line break.

An example can be seen here: https://regex101.com/r/b8zN8u/2

The HTML i am trying to extract looks like this:

<script>
  DATA.tracking.user = { 
      age: "19", 
      name: "John doe" 
  }
</script>

Using the following regex: DATA.tracking.user=(.*?)}

<?php
$re = '/DATA.tracking.user = (.*?)\}/m';
$str = '<script>
           DATA.tracking.user = { age: "19", name: "John doe" }
        </script>';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

If i parse DATA.tracking.user = { age: "19", name: "John doe" } without any linebreaks, Then it works fine but if i try to parse:

DATA.tracking.user = { 
      age: "19", 
      name: "John doe" 
  }

It does not like dealing with the line breaks.

Any help would be greatly appreciated.

Thanks.

  • 写回答

4条回答 默认 最新

  • douliang1369 2018-05-08 07:48
    关注

    The simple solution to your problem is to use the s pattern modifier to command the . (any character) to also match newline characters -- which it does not by default.

    And you should:

    • escape your literal dots.
    • write the \{ outside of your capture group.
    • omit the m pattern modifier because you aren't using anchors.

    ...BUT...

    If this was my task and I was going to be processing the data from the extracted string, I would probably start breaking up the components at extraction-time with the power of \G.

    Code: (Demo) (Pattern Demo)

    $htmls[] = <<<HTML
    DATA.tracking.user = { age: "19", name: "John doe", int: 55 } // This works
    HTML;
    
    $htmls[] = <<<HTML
    DATA.tracking.user = { 
        age: "20", 
        name: "Jane Doe",
        int: 49
    } // This does not works
    HTML;
    
    foreach ($htmls as $html) {
        var_export(preg_match_all('~(?:\G(?!^),|DATA\.tracking\.user = \{)\s+([^:]+): (\d+|"[^"]*")~', $html, $out, PREG_SET_ORDER) ? $out : []);
        echo "
     --- 
    ";
    }
    

    Output:

    array (
      0 => 
      array (
        0 => 'DATA.tracking.user = { age: "19"',
        1 => 'age',
        2 => '"19"',
      ),
      1 => 
      array (
        0 => ', name: "John doe"',
        1 => 'name',
        2 => '"John doe"',
      ),
      2 => 
      array (
        0 => ', int: 55',
        1 => 'int',
        2 => '55',
      ),
    )
     --- 
    array (
      0 => 
      array (
        0 => 'DATA.tracking.user = { 
        age: "20"',
        1 => 'age',
        2 => '"20"',
      ),
      1 => 
      array (
        0 => ', 
        name: "Jane Doe"',
        1 => 'name',
        2 => '"Jane Doe"',
      ),
      2 => 
      array (
        0 => ',
        int: 49',
        1 => 'int',
        2 => '49',
      ),
    )
     --- 
    

    Now you can simply iterate the matches and work with [1] (the keys) and [2] (the values). This is a basic solution, that can be further tailored to suit your project data. Admittedly, this doesn't account for values that contain an escaped double-quote. Adding this feature would be no trouble. Accounting for more complex value types may be more of a challenge.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 C++ /QT 内存权限的判断函数列举
  • ¥15 深度学习GFnet理解问题
  • ¥15 单细胞小提琴堆叠图代码
  • ¥80 LS dyna mpp并行报错
  • ¥50 升级strust2版本到2.3.15.1后使用ognl3.0.6.jar windows环境中没有问题,但部署到linux环境报错
  • ¥15 vue页面,node封装接口
  • ¥15 求TMS320F280039C工程模板!
  • ¥15 delphi+fastreport实现分组补空打印问题
  • ¥15 使用python把两台mysql数据库服务器数据导出和导入
  • ¥15 NodeBB论坛配置Apache Solr中文搜索引擎的详细教程