2011-06-10 117 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