使用正则表达式(PHP)从HTML页面提取JSON

使用正则表达式(PHP)从HTML页面提取JSON,php,regex,Php,Regex,我有一个HTML页面,在脚本标记中有一个非常大、非常复杂的JSON块 我想提取JSON,以便在php脚本中对其进行解码 JSON看起来像: <script type="text/javascript"> var user_list_data_obj = ( ({ ... truncated ... }) ); ... some more js ... </script> 它什么也不返回 我在这种模式下做错了什么?我知

我有一个HTML页面,在脚本标记中有一个非常大、非常复杂的JSON块

我想提取JSON,以便在php脚本中对其进行解码

JSON看起来像:

<script type="text/javascript">
    var user_list_data_obj = (
    ({

    ... truncated ...

    })
    );

    ... some more js ...
</script>
它什么也不返回

我在这种模式下做错了什么?我知道很难将任何具有开始和结束分隔符(如JSON)的东西与正则表达式匹配,但在这种情况下应该是可能的,不是吗

编辑:

我试图将整个“user\u list\u data\u obj”对象解析到我的php脚本中。但实际上,我感兴趣的是几个“columns:[]”数组,因此如果更容易将它们分开,那么这样做可能是有意义的

列[]数组类似于

columns : [
       { display_value : '<input type="checkbox" name="user" value="username">'}, 
       { display_value : 'username', sort_value : 'username'}, 
       { display_value : 'username', sort_value : 'username'}, 
       { display_value : 'Enabled', sort_value : '1' },
       { display_value : '<img class="" src="/enabled.gif">', sort_value : '1' }, 
       { display_value : '<img class="" src="/enabled.gif">', sort_value : '1' },
       { display_value : '<img class="" src="/enabled.gif">', sort_value : '1' }
       ],
列:[
{显示值:''},
{显示值:'username',排序值:'username'},
{显示值:'username',排序值:'username'},
{显示值:'Enabled',排序值:'1'},
{显示值:'',排序值:'1'},
{显示值:'',排序值:'1'},
{显示值:'',排序值:'1'}
],

我能找到的最接近的是

preg_match('/var user_list_data_obj = \(\s+\(({.*})\)\s+\);/s', $html, $matches);
s
修改器允许匹配换行符

这是不完美的,因为它对结构做出了假设:也就是说,您需要的JSON从字面上开始

( /* some space */
({

}) /* some space */
);

如果您不能做出这些假设,那么一个不太具体的正则表达式可能会匹配脚本的其他部分。另外,如果您有
})在脚本中某个您不想匹配的点上,它仍将被匹配。使用
{.*?}
将不起作用,因为要捕获的字符串中可能有许多嵌套对象文本。

我能够将整个json对象与以下内容匹配

/user_list_data_obj\s*=\s*\(\s*\({(.*?)}\)\s*\);/
但实际上,我最终使用preg_match_all来匹配json中的每个列[]数组,方法是:

/columns\s*:\s*\[.*?\],/s

您是否尝试对多行使用m修饰符?JSON语法不规则,因此您需要依赖JSON前后的文本来查找其边界。你能在它出现的上下文上展开吗?@MikeSamuel我添加了一个有实际示例的粘贴箱,你可以在其中看到上下文。@AmitKriplani:Multiline mode(
m
)在这里不相关。它会更改他未使用的锚(
^
$
)的行为。正是单线模式(
s
)让点匹配行分隔符字符。啊,是的,在查看了您的表达式后,我确实看到了我在表达式中出错的地方,但不幸的是,两者都无法提取我试图提取的内容。看起来JSON的内容可能会引起一些麻烦。这里有一个真实的例子,我正试图提取:你救了我一天!我做了一点修改,对于那些没有
regex:
datasource\s*=\s*\s*{(.*)}\s*;
的人来说效果很好,并且得到了实际的json:
(?)?
/columns\s*:\s*\[.*?\],/s