2011-06-10 64 views
3

我想写一个(我认为)非常简单的正则表达式与PHP,但它不工作。 基本上我有这样定义的模块:与PHP正则表达式解析块

%%%%blockname%%%% 
stuff goes here 
%%%%/blockname%%%% 

我没有任何好处的正则表达式,但是这是我的尝试:

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

它返回一个4个空条目的数组。

我想它除了实际工作之外,还需要某种类型的第三次比赛指针,因为它应该等于第一次?

请赐教:)

+1

如果您没有嵌套块,则不必担心与第一个匹配的第三个匹配项。另一方面,如果你有嵌套块,正则表达式可能不会成为现实.. – 2011-06-10 07:40:27

+0

我现在没有嵌套块,但可能在将来。我也想过也许使用HTML解析器,并通过给我的HTML代码赋予属性来定义块。 – Kokos 2011-06-10 07:41:54

回答

8

你需要使点匹配换行符,并允许^$以匹配行的开始和结束(不只是整个字符串):

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

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

m(多行)选项允许^$在行的开始和结尾匹配。

i选项在您的正则表达式中是不必要的,因为它没有区分大小写的字符。通过使用反向引用第一个捕获组如果blockname是一样的在这两种情况下,那么你就可以做出明确的:

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

好点,虽然这不是对科科斯问题的真正答案。 – elslooo 2011-06-10 07:39:42

+0

我想'\ 1'然后是指第一个匹配,每天学习东西:) – Kokos 2011-06-10 07:44:03

+1

'\ n'是指正则表达式中第n个捕获组(括号集)的内容。在另一个评论中你提到过你可能会嵌套块。这是它变得复杂的地方。它可以完成,但至少可以说是多毛的。 – 2011-06-10 07:46:48

0

然后,回答你问题的第二部分很确定你不能这样做,因为这些操作需要保存一个变量,而你不能以正则表达式。您应该尝试使用PHP的内置令牌解析器来执行此操作。 http://php.net/manual/en/function.token-get-all.php

+0

你是什么意思,你不能在正则表达式中保存一个变量?当我说'$ matches'将包含匹配的内容时,我不认为我错过了某些东西。 – Kokos 2011-06-10 07:43:12

+0

'$ matches'是PHP。但是如果你不想匹配打开和关闭标签,它必须保存第一个标签并只搜索匹配的结束标签(而不是任何结束标签)。 – elslooo 2011-06-10 14:01:45

+0

我不确定我是否误解了你,但是Tim Pietzcker给出的答案确实允许我在单个RegEx中匹配开始和结束标签(并且我不明白为什么它不应该成为可能)。 – Kokos 2011-06-10 14:21:02