Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用php正则表达式解析块_Php_Regex_Block - Fatal编程技术网

用php正则表达式解析块

用php正则表达式解析块,php,regex,block,Php,Regex,Block,我试图用PHP编写一个(我认为)非常简单的正则表达式,但它不起作用。 基本上我有一个块定义如下: %%%%blockname%%%% stuff goes here %%%%/blockname%%%% 我不擅长正则表达式,但这就是我所尝试的: preg_match_all('/^%%%%(.*?)%%%%(.*?)%%%%\/(.*?)%%%%$/i',$input,$matches); 它返回一个包含4个空条目的数组 我猜,除了实际工作之外,它还需要第三个匹配的指针,因为它应该等于第一个

我试图用PHP编写一个(我认为)非常简单的正则表达式,但它不起作用。 基本上我有一个块定义如下:

%%%%blockname%%%%
stuff goes here
%%%%/blockname%%%%
我不擅长正则表达式,但这就是我所尝试的:

preg_match_all('/^%%%%(.*?)%%%%(.*?)%%%%\/(.*?)%%%%$/i',$input,$matches);
它返回一个包含4个空条目的数组

我猜,除了实际工作之外,它还需要第三个匹配的指针,因为它应该等于第一个匹配


请告诉我:)

您需要允许点匹配换行符,并允许
^
$
在行首和行尾匹配(不仅仅是整个字符串):

s
(单行)选项使点匹配任何字符,包括换行符

m
(多行)选项允许
^
$
在行首和行尾匹配

i
选项在正则表达式中是不必要的,因为其中没有区分大小写的字符

然后,回答问题的第二部分:如果
blockname
在两种情况下都相同,那么您可以使用对第一个捕获组的反向引用来明确这一点:

preg_match_all('/^%%%%(.*?)%%%%(.*?)%%%%\/\1%%%%$/sm',$input,$matches);

我很确定你不能,因为这些操作需要保存一个变量,而你不能在正则表达式中保存。您应该尝试使用PHP的内置令牌解析器来实现这一点

很好,虽然这并不是对Kokos问题的回答。我想
\1
然后指的是第一场比赛,每天学点东西:)
\n
指的是正则表达式中第
n
个捕获组(括号集)的内容。在另一条评论中,您提到将来可能会有嵌套块。这就是问题变得复杂的地方。这是可以做到的,但至少可以说是有问题的。我发现我的HTML输入有问题,
%%%%%blockname%%%%
是缩进的,所以我猜
^
不允许匹配它,因为它不是行中的第一件事。在这种情况下,只需将
\s*
添加到
^
之后和/或
$
之前。如果没有嵌套块,则无需担心第三个匹配与第一个匹配。另一方面,如果你有嵌套的块,正则表达式可能不是解决的办法。我现在没有嵌套块,但将来可能会有。我还考虑过使用一个HTML解析器,通过给我的HTML代码赋予属性来定义块。你说不能在正则表达式中保存变量是什么意思?当我说
$matches
将包含匹配的内容时,我并不认为我遗漏了什么。
$matches
是PHP。但是如果你不想让正则表达式匹配开始和结束标记,它必须保存第一个标记并只搜索匹配的结束标记(而不是任何结束标记)。我不确定我是否误解了你,但是Tim Pietzcker给出的答案允许我在单个正则表达式中匹配开始和结束标记(我不明白为什么一开始就不可能)。请重新阅读这个问题。他要求一个可以检测匹配(嵌套)结束标记的正则表达式。(例如:
..
..
,将给出
a…b
而不是
b…b…a…a
preg_match_all('/^%%%%(.*?)%%%%(.*?)%%%%\/\1%%%%$/sm',$input,$matches);