...
PHP 正则表达式

php正则获取网页中的json

php正则获取网页中的json

应用场景
爬取网页中js变量json值
正则表达式

/(?<json>\s*(?:\{\s*(?:\s*"[^"]+"\s*:\s*(?<value>(?:(?P>json)|true|false|null|-?\d+(?:\.\d+)?|"[^"]*")\s*,?)\s*)*\s*\}|\[\s*(?P>value)*\s*\])\s*)/

主要知识点
(?\) 声明一个命名分组,php可用 (?P>json) 调用它,可以理解为声明了一个变量。

还有在match输出的时候将输出key变成json,如下:

preg_match('/^(?<text>.*)$/','test',$match);
print_r($match);
// print $match
/**
Array => (
    0 => test,
    text => test
)
**/

(?:) 非捕获分组 因为我们大量的使用了 | 或 符号避免输出环境中出现无用的数据,我们可以采用(?:)来取消分组的内容捕获,如下所示:

//无(?:)
preg_match('/^(?<text>(a|b)(.*))$/','atest',$match);
print_r($match);
// print $match
/**
Array => (
    0 => atest,
    1 => a,
    text => test
)
**/
//有(?:)
preg_match('/^(?<text>(?:a|b)(.*))$/','atest',$match);
print_r($match);
// print $match
/**
Array => (
    0 => atest,
    text => test
)
**/

(?P>json) 递归子表达式,怎么理解这个呢,很简单 就是在 (?\) 声明命名分组的时候 (?P>name)就可以调用name的正则使用了,还有一个(?p=name)两者的区别是(?P>name)是直接拿人家的表达式来用,(?P=name)是拿人家的匹配结果来用。类似于:

$input = '【a】123【b】321【d】';
//普通的正则
/^【[a-z]】\d+【[a-z]】\d+【[a-z]】$/
//使用命名分组
/^(?<group>【a-z】)\d+(?P>group)\d+(?P>group)$/
//代码可能写的有点多余了,但就是这个原理,之说原理哦
/**
print Array
(
    [0] => 【a】123【b】321【d】
    [group] => 【a】
    [1] => 【a】
)
**/

(?p=name) 匹配name表达式的捕获结果,这个对html标签特有用,如下:

$input = '<div>123</div>'
//正则
/^<(?<group>[^>]+)>(.+?)<\/(?P=group)>$/
/**
print Array
(
    [0] => <div>123</div>
    [group] => div
    [1] => div
    [2] => 123
)
//group就是对前标签的一个复制
**/

正则分解详解

1.先看{}的匹配

\{\s*(?:\s*"[^"]+"\s*:\s*(?\<value>(?:true|false|null|-?\d+|"[^"]+"|(?P>json))\s*,?)\s*)*\s*\}

可将上面的正则分成三部分

//json的key  匹配不是双引号结尾的所有值
\s*"[^"]+"\s*

记得还有个: 冒号

//json的value 对value做一个命名分组 匹配各种数据类型  (?P>json)是调用json分组的正则
\s*(?\<value>(?:true|false|null|-?\d+|"[^"]+"|(?P>json))\s*

//还有逗号, 可有可无

,?

以上三项组成一个json的对象

2.[] 的匹配
数组的匹配相对简单

//直接调用了{}匹配中的value命名分组
\[\s*(?P>value)*\s*\]

3.(?\对象|数组) 合成一个json的捕获正则
使用
网页内容:

...
var pureViewPageDataRR = {"docInfoFromApi":{"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}};
...

正则获取pureViewPageDataRR 内容:

preg_match('/(?<json>\s*(?:\{\s*(?:\s*"[^"]+"\s*:\s*(?<value>(?:(?P>json)|true|false|null|-?\d+(?:\.\d+)?|"[^"]*")\s*,?)\s*)*\s*\}|\[\s*(?P>value)*\s*\])\s*)/','var pureViewPageDataRR = {"docInfoFromApi":{"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}};',$match);
print_r($match);
//输出结果:
/**
Array
(
    [0] =>  {"docInfoFromApi":{"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}}
    [json] =>  {"docInfoFromApi":{"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}}
    [1] =>  {"docInfoFromApi":{"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}}
    [value] => {"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}
    [2] => {"doc_id":"dd6213a9e63a580216fc700abb68a98271feacf9"}
)
**/
//完美!!!

参考
https://www.cnblogs.com/Kevin-Yang/p/11444118.html

下面这个手册没有找到出处,原文也是截图。

PHP CURL采集乱码解决办法 win11 桌面不满足要求水印去除 适用于跳过TPM CPU检测安装后的桌面水印
biu biu biu
Linux命令大全(手册) Content-Type 对应的格式 Ubuntu20.04 设置开机自启动 github无法访问,访问速度慢解决 常用的前端JavaScript方法封装