微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

正则表达式获取PHP中大括号标签之间的字符串

如何解决正则表达式获取PHP中大括号标签之间的字符串

$HTML:

{list:start:Data}
   {id} is having a title of {title}
{list:end:Data}

数据是动态的,可以是任何字符串。

我正在尝试使用以下代码循环所有出现的内容

preg_match_all('/\{list:start:(.*?)\}(.*?)\{list:end:(.*?)\}/',$HTML,$match);

我想要以下结果:

$match = array(
   array(
      "string" => "Data","value" => "{id} is having a title of {title}"
   )
);

但我得到以下结果:

$match = array(
   [0] => Array
        (
        )

    [1] => Array
        (
        )

    [2] => Array
        (
        )

    [3] => Array
        (
        )
);

但这不起作用,因为 $match 返回一个空数组。经过几个小时的寻找解决方案后,我仍然没有接近工作结果。

解决方法

作为替代方案,您可以使用 negated character class 而不是使用 .*?/s 修饰符来使点匹配换行符。

如果您不想匹配以 {list: 开头的连续行,您可以使用负前瞻来排除这些匹配。

^{list:start:([^}]+)}\R((?:(?!{list:).*\R)*+){list:end:[^}]+}

模式匹配:

  • ^ 字符串开头
  • {list:start: 逐字匹配(注意 { 不需要转义)
  • ( 捕获组 1
    • [^}]+ 匹配除 } 之外的任何字符 1+ 次
  • ) 关闭第 1 组
  • } 匹配结束 }
  • \R 匹配任何 unicode 换行符序列
  • ( 捕获 第 2 组
    • (?:(?!{list:).*\R)*+ 重复匹配所有不以 list: 开头的行
  • ) 关闭第 2 组
  • {list:end: 逐字匹配
  • [^}]+ 匹配除 } 之外的任何字符 1+ 次
  • } 匹配结束 }

看到一个 regex demo 和一个 Php demo

示例代码

$re = '/^{list:start:([^}]+)}\R((?:(?!{list:).*\R)*){list:end:[^}]+}/m';
$str = '{list:start:Data}
   {id} is having a title of {title}
{list:end:Data}

{list:start:Data}
{list:start:Data}
   {id} is having a title of {title}
this is some text
{list:end:Data}';

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

print_r(array_map(function($x){
    return [
        "string" => $x[1],"data" => trim($x[2])
    ];
},$matches));

输出

Array
(
    [0] => Array
        (
            [string] => Data
            [data] => {id} is having a title of {title}
        )

    [1] => Array
        (
            [string] => Data
            [data] => {id} is having a title of {title}
this is some text
        )

)
,

您需要对大括号进行转义,并使用 /s 匹配多行。下面是代码示例。


代码

<?php

$input = '
{list:start:Data}
   {id} is having a title of {title}
{list:end:Data}

{list:start:Data1}
   {id1} is having a title of {title1}
{list:end:Data1}

{list:start:Data2}
   {id2} is having a title of {title2}
{list:end:Data2}

{list:start:Data3}
   {id3} is having a title of {title3}
{list:end:Data3}

';

preg_match_all(
    "/\\{list:start:(.+?)\\}(.*?)\\{list:end:(.+?)\\}/s",$input,$preg_matches
);

$matches = [];
foreach ($preg_matches[1] as $k => $v) {
    $matches[] = [
        "string" => trim($v),"data" => trim($preg_matches[2][$k])
    ];
}

print_r($matches);

输出

Array
(
    [0] => Array
        (
            [string] => Data
            [data] => {id} is having a title of {title}
        )

    [1] => Array
        (
            [string] => Data1
            [data] => {id1} is having a title of {title1}
        )

    [2] => Array
        (
            [string] => Data2
            [data] => {id2} is having a title of {title2}
        )

    [3] => Array
        (
            [string] => Data3
            [data] => {id3} is having a title of {title3}
        )

)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。