正则表达式只匹配第一个内容

时间:2017-03-08 20:02:00

标签: php regex

我有以下HTML代码。

<script type="application/ld+json">
    {"foo" : "bar"}
</script>

<script type="application/ld+json">
    {"foo" : "bar"}
</script>

<script type="application/ld+json">
    {"foo" : "bar"}
</script>

我试图从第一个脚本中获取json内容。但是如果我做的话

/<script type="application\/ld\+json">{.*}<\/script>/

它在第一个脚本开始标记和最后一个脚本结束标记之前提供所有内容。如果我做

/<script type="application\/ld\+json">{.*?}<\/script>/

出于某种原因,我只得到了第二部分。

无论如何从第一个标签中获取{} json部分?

4 个答案:

答案 0 :(得分:3)

它甚至不应该编译..但无论如何看起来你混淆了贪婪和不同意和括号的类型,{X}意味着之前的组可以有x个时间量,而不是x中任何数量的时间是[] *

你需要的是这样的东西

/<script type="application\/ld\+json">[^\{]*?{(.*?)\}[^\}]*?<\/script>/s

使用从preg_match返回的匹配对象中的对象索引1,您将获得JSON。

repl.it用于运行PHP示例(下面的代码):https://repl.it/GNdD/0

链接以尝试使用正则表达式:https://regex101.com/r/AouzRm/10

$in = '<script type="application/ld+json">';
$in .= '{"foo" : "bar"}';
$in .= '</script>';

$in .= '<script type="application/ld+json">';
$in .= '    {"foo" : { "bar" : "boo" } }';
$in .= '</script>';

$in .= '<script type="application/ld+json">';
$in .= '    {"foo" : { "bar" : { "boo" : "goo" }}}';
$in .= '</script>';

$matches = [];
$allMatches = [];

preg_match('/<script type="application\/ld\+json">[^\{]*?{(.*?)\}[^\}]*?<\/script>/s',$in,$matches);
preg_match_all('/<script type="application\/ld\+json">[^\{]*?{(.*?)\}[^\}]*?<\/script>/s',$in,$allMatches);

echo "from the preg_match:\n";
print_r("$matches[1]\n\n");

echo "from the preg_match_all:\n";
print_r($allMatches[1]);

答案 1 :(得分:1)

正如@Denziloe所说,你的正则表达式看起来没问题。

这可能是一个问题,因为您没有考虑脚本标记中的换行符和空格。

检查此示例,看看是否修复了它,否则您的实现可能出现问题。我还认为你想像我一样添加一个捕获组,以便更容易地访问JSON部分本身

<script type="application\/ld\+json">\s*({.*?})\s*<\/script> working example

答案 2 :(得分:1)

尝试使用以下正则表达式

(?s)>.*?(?={)\K.*?}

参见 regex demo / explanation

PHP demo

$r = '/(?s)>.*?(?={)\K.*?}/';
$s = '<script type="application/ld+json">
    {"foo1" : "bar1"}
</script>

<script type="application/ld+json">
    {"foo2" : "bar2"}
</script>

<script type="application/ld+json">
    {"foo3" : "bar3"}
</script>';
preg_match($r, $s, $o);
print_r($o);

答案 3 :(得分:1)

从PHP的角度来看......也许你没有正确访问$matches? 假设您想要以下示例中的{"one" : "bar"}

<?php

$html = '<script type="application/ld+json">
    {"one" : "bar"}
</script>

<script type="application/ld+json">
    {"two" : "bar"}
</script>

<script type="application/ld+json">
    {"three" : "bar"}
</script>';

$pattern = '/<script type="application\/ld\+json">\s*(\{.*?\})\s*<\/script>/s';

preg_match_all($pattern, $html, $matches);

$whatYouWant = $matches[1][0];

echo $whatYouWant;

You can see the execution of this code here