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 Python爬取指定微博话题下的内容,保存为txt
  • ¥15 vue2登录调用后端接口如何实现
  • ¥65 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?