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