2014-07-25 13 views
1

我試圖捕獲由字母,數字和下面的%符號組成的下劃線組成的文本的每個實例,只要它不是%%或轉義百分比。我寫了下面的正則表達式來做到這一點:使用D捕獲和存儲正則表達式的所有匹配使用D

((?<!(?:\\|%))%[a-zA-Z0-9_]+)

我想保存它抓住以這種方式爲關聯數組的一切,所以我寫了下面的函數來做到這一點:

string[string] make_symbol_table(string input) { 
    string[string] symbol_table; 
    auto m = matchAll(input, regex(r"((?<!(?:\\|%))%[a-zA-Z0-9_]+)", "g")).captures(); 
    for (auto i = 1; i < m.length; i++) { 
    symbol_table[m[i]] = null; 
    } 
    return symbol_table; 
} 

並測試了以下輸入:

This is an ordinary %template, with a few well-situated %template_arguments. It uses a range of characters, mostly to ensure that %template1 works correctly.\n\nYou can even start %1template with a number! We can also have some silly cases: %_ %1, %a, and so on. %%DIRECTIVES should never be captured, nor should escaped \\% or \\%\\%. %CAPS or %CaPs are fine too.

,我已經寫了作爲一個轉義字符串。我認爲這會給我9場比賽(由this確認),但由於某種原因,我只得到1!我是否正確使用matchAll

回答

1

.captures.front相同,即第一次匹配。你對所有比賽都感興趣。所以放下.captures

然後,mRegexMatch,它沒有.length。只需foreach就可以了:foreach(match; m)

matchCaptures,即完全匹配和所有子匹配的範圍。您對完整匹配感興趣*。因此,使用match.frontmatch[0]得到的字符串:symbol_table[match.front] = null;

*或第一個子匹配 - 它們是相同的,因爲整個事情是括號


也許這可以幫助明確了一點東西:

  • matchAll(...)返回範圍匹配:
    • 第一匹配是全場比賽和理論值的一個範圍Ë子匹配:
      • 全場比賽: 「%模板」
      • 1子匹配: 「%模板」
    • 第二節比賽同上:
      • 全場比賽: 「%template_arguments」
      • 1個子匹配:「%template_arguments」
    • 第3個匹配同上:
      • 全場比賽: 「%模板1」
      • 1子匹配: 「%模板1」
    • ...
0
(?<!\\)(?<!%)%[a-zA-Z0-9_]+ 

這在Python中適用於我。

相關問題