2014-02-26 101 views
2

PropDefinition是這樣的形式prop\d+ (true|false)正則表達式匹配的重複圖案僅串後

的字符串我有這樣的字符串:

((prop5 true)) 

sat 
((prop0 false) 
(prop1 false) 
(prop2 true)) 

我想提取底部PropDefinitions只有在文本'坐'後,所以比賽應該是:

prop0 false 
prop1 false 
prop2 true 

我來源使用/(prop\d (?:true|false))/ssee example here)盟友試圖但顯然所有PropDefinitions比賽,我不能讓它只是sat字符串匹配後重復

我用rubular作爲一個例子,因爲以上這很方便,但我真的很尋找最不可知的語言解決方案。如果它是重要的信息,我很可能會在Java應用程序中使用正則表達式。

+4

應用正則表達式將會使您的生活更輕鬆之前拆分您輸入的字符串。 – beerbajay

+0

嵌套怎麼樣?什麼語言?它支持'\ G'錨嗎?它支持遞歸嗎? – sln

+0

我想要一個不涉及拆分字符串的版本。我真的正在尋找一個可以滿足好奇心的正則表達式。我可以絕對分開坐在,然後只是正則表達式後,但我會學習更少:) –

回答

-2
/(?<=sat).*?(prop\d (true|false))/m 

比賽第1組是你想要的。請參閱example

但是,我真的建議先拆分字符串。這很容易。

+1

您只返回prop0 false,沒有其他匹配。他希望所有3個道具的定義。 –

+0

@DaniëlKnippers它一次匹配一個。重複它,你會得到所有的人。 –

0
str =<<-Q 
((prop5 true)) 

sat 
((prop0 false) 
(prop1 false) 
(prop2 true)) 
Q 

p str[/^sat(.*)/m, 1].scan(/prop\d+ (?:true|false)/) 

# => ["prop0 false", "prop1 false", "prop2 true"] 
+0

您的正則表達式也一次匹配一個。魔法發生在'scan'方法中,而不是你的正則表達式。 –

+1

我每個屬性都會返回一個單獨的匹配項,當您必須逐個讀取屬性時,無法使用1個字符串? –

0

當你在這種情況下是非常不同的性質爲(sat後串並選擇特定的模式)模式,它通常是更好地表達他們在多個正則表達式,而不是試圖用做單個正則表達式。混亂的

s = <<_ 
((prop5 true)) 

sat 
((prop0 false) 
(prop1 false) 
(prop2 true)) 
_ 

s.split(/^sat\s+/, 2).last.scan(/prop\d+ (?:true|false)/) 
# => ["prop0 false", "prop1 false", "prop2 true"] 
+1

嗯,好像分裂的第一個是建議的方式,然後... –

0

部分具有單線VS多行匹配的事情。下面的模式適用於我,並且在一次執行中返回所有匹配,並且不需要進行初步操作來拆分字符串。

這一個需要單線模式下(在.net RegExOptions如)分別規定:

(?<=sat.*)(prop\d (?:true|false)) 

這一個指定單線模式內嵌其中許多工作,但不是全部,正則表達式引擎:

(?s)(?<=sat.*)(?-s)(prop\d (?:true|false)) 

您不需要需要通過(?-s)關閉SingleLine模式,但我認爲它的意圖更清晰。

以下模式也會內聯切換SingleLine模式,但使用Negative LookAhead而不是Positive LookBehind(按照regular-expressions.info [請務必從下拉列表中選擇Ruby和Java]),但Ruby引擎不會「 t支持LookBehinds - 正面還是負面 - 取決於版本,即使這樣也不允許量詞(在下面的評論中也被@revo指出)。這種模式應該在Java中工作。網絡,最有可能的紅寶石,其他:

(prop\d (?:true|false))(?s)(?!.*sat)(?-s) 
+0

看後面的斷言不支持量化紅寶石 – revo

0

如果紅寶石可以支持\G錨,這是一個解決方案。
看起來很討厭,但有幾件事情正在發生。
1.它僅允許一個單一的巢(外加上許多內部件)
2.將不匹配不與'(prop\d true|false)'

遵守沒有條件2無效的形式,這將是容易得多,其是指示那兩個正則表達式解決方案也會這樣做。首先捕獲外部表格sat((..)..(..)..) 秒以全局捕捉內部表格(prop\d true|false)

可以在一個正則表達式中完成,雖然這將很難看,但應該工作(在Perl中測試用例如下)。

# (?:(?!\A|sat\s*\()\G|sat\s*\()[^()]*(?:\((?!prop\d[ ](?:true|false)\))[^()]*\)[^()]*)*\((prop\d[ ](?:true|false))\)(?=(?:[^()]*\([^()]*\))*[^()]*\)) 

(?: 
     (?! \A | sat \s* \() 
     \G       # Start match from end of last match 
    |        # or, 
     sat \s* \(     # Start form 'sat (' 
) 
[^()]*      # This check section consumes invalid inner '(..)' forms 
(?:       # since we are looking specifically for '(prop\d true|false)' 
     \( 
     (?! 
      prop \d [ ] 
      (?: true | false) 
      \) 
    ) 
     [^()]* 
     \) 
     [^()]* 
)*       # End section, do optionally many times 
\( 
(       # (1 start), match inner form '(prop\d true|false)' 
     prop \d [ ] 
     (?: true | false) 
)        # (1 end) 
\) 
(?=       # Look ahead for end form '(..)(..))' 
     (?: 
      [^()]* 
      \([^()]* \) 
    )* 
     [^()]* 
     \) 
) 

Perl的測試用例

$/ = undef; 

$str = <DATA>; 

while ($str =~ /(?:(?!\A|sat\s*\()\G|sat\s*\()[^()]*(?:\((?!prop\d[ ](?:true|false)\))[^()]*\)[^()]*)*\((prop\d[ ](?:true|false))\)(?=(?:[^()]*\([^()]*\))*[^()]*\))/g) 
{ 
    print "'$1'\n"; 
} 

__DATA__ 
((prop10 true)) 
sat 
((prop3 false) 
(asdg) 

(propa false) 

(prop1 false) 
(prop2 true) 
) 
((prop5 true)) 

輸出>>

'prop3 false' 
'prop1 false' 
'prop2 true'