2013-05-16 48 views
4

當我使用正則表達式<@(.+?)@>匹配的模式,如:獲取外「配對」嵌套

<@set:template default.spt @> 

它工作正常,但我碰到的地方,我需要嵌套模式的情況下,這樣的因爲這樣:

<@set:template <@get:oldtemplate @> @> 

而不是獲取父對(< @和@>)我得到以下幾點:

<@set:template <@get:oldtemplate @> 

我不希望它得到孩子,我只是想在所有嵌套情況下的最外層父母。如何修復我的正則表達式,以便它能爲我做到這一點?我想我可以做到這一點,如果我知道如何要求每個<@父母內部有一個@>,但我不知道如何執行該操作。

+0

哪種語言? –

+0

@CasimiretHippolyte Python – FreeSnow

+0

您需要使用'regex'軟件包來執行此操作。默認的're'包不能處理任意的嵌套級別。 – nhahtdh

回答

5

你描述的是一種「非正規語言」。它不能用正則表達式解析。

好的,如果你願意限制嵌套級別,在技術上你可以做一個正則表達式。但它會很醜。

這裏是如何與解析你的事情了您的一些標籤內(增加)最大嵌套深度,如果你可以把沒有的條件@的:

no nesting: <@[^@][email protected]> 
up to 1: <@[^@]+(<@[^@][email protected]>)?[^@]*@> 
up to 2: <@[^@]+(<@[^@]+(<@[^@][email protected]>)?[^@]*@>)?[^@]*@> 
up to 3: <@[^@]+(<@[^@]+(<@[^@]+(<@[^@][email protected]>)?[^@]*@>)?[^@]*@>)?[^@]*@> 
... 

如果你不能禁止孤獨@在你的代碼中,你將不得不用[^@]這樣的東西來替換每個實例:(?:[^<@]|<[^@]|@[^>])

試想一下,然後考慮擴展你的正則表達式來解析10個深度嵌套。

在這裏,我會爲你做它:

<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[ 
^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|< 
[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@[^>])+(<@(?:[^<@]|<[^@]|@ 
[^>])+(<@(?:[^<@]|<[^@]|@[^>])[email protected]>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>] 
)*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@ 
>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@>)? 
(?:[^<@]|<[^@]|@[^>])*@>)?(?:[^<@]|<[^@]|@[^>])*@> 

我希望我的回答所示的是正則表達式不解析語言的工具。傳統的詞法分析器(標記器)和解析器組合會做得更好,速度更快,並且可以處理無限的嵌套。

+0

可以允許使用'@'和'>',而不用'(?:(?!@>)消耗結束標記。得到最終結果。 – nhahtdh

1

我不認爲你可以用正則表達式來做到這一點,請參閱this question的答案,其中提供了類似的東西。正則表達式不足以處理任意級別的嵌套,如果你只有兩層嵌套,那麼它應該是可能的,但也許正則表達式不是工作的最佳工具。