2014-03-06 51 views
1

我想找到一種方法來在.NET中使用正則表達式來有效地確定哪些字符串匹配的模式。如果我的令牌是固定文本,我會使用字典<>並簡單地查看它們。但是,令牌可能會嵌入一個或多個數字序列來表示索引。我有幾十到幾百個這樣的代幣。對於一個小例子,我想匹配以下標記中的一個:使用正則表達式高效地解析/ lex令牌

ORDERID 
PRICE(\d+) 
QUANTITY(\d+) 
DESCRIPTION(\d+) 
WEIGHT(\d+)_(\d+) 

(想象的使用情況是,我有一組名值對,而名稱使用嵌入式的整數,以允許重複在在這個例子中,想象一個有多行的訂單,PRICE是第n行的價格,WEIGHT_是第n行第m個單獨對象的權重(假設lineitem是某種套件))。

請注意,這些令牌的組成超出了我的控制範圍。

我可以有效的東西識別這些標記像

^(?<oid>ORDERID)|(?<prc>PRICE(\d+))|(?<qty>QUANTITY(\d+)|(?<dsc>DESCRIPTION(\d+)|(?<wght>WEIGHT(\d+)_(\d+)$ 

注意,正則表達式對於給定的正規快件匹配是你匹配字符串的大小呈線性關係,它不應該超過由於我添加了更多的令牌,因此日誌效率不高。

現在做一個匹配:

Match m = r.Match("PRICE44") 

不幸的是,據我所知,以確定哪些令牌從Regex.Match對象匹配,我已經通過了所有的可能性進行迭代:

m.Groups["oid"].Success 
m.Groups["prc"].Success 
m.Groups["qty"].Success 
m.Groups["dsc"].Success 
m.Groups["wght"].Success 

隨着令牌數量的增加,成本會線性增長(或更可能是n log n)。如果有,例如SuccessGroups集合,我可以遍歷它,它通常(在我的使用中)具有單個元素:匹配的特定組。

我可以編寫自己的解析算法來創建一個trie或類似的數據結構,但我不願意重新實現Regex已經實現的東西,但似乎並沒有給我有效的訪問權限。

任何想法或建議嗎?

+0

相比執行正則表達式迭代組的名單應該是毫無意義權的費用迭代?你的基準測試顯示了什麼? – Slugart

+0

不對。匹配一個預編譯的正則表達式實際上是非常有效的:它是一個確定性的有限狀態自動機,它的執行在匹配的輸入字符串的長度上大致是線性的(如果你願意空間低效,它可以是線性的,但您通常會使用更節省空間的結構來確定給定輸入字符的下一個狀態,這可能與下一個可能字符的數量成線性關係,或者在下一個字符的數量中記錄n)。 –

+0

我用我需要識別的80個標記做了一個簡單的測試。我做了這場比賽,然後我進行了比賽,接着迭代各組以找到成功的比賽。迭代通過組的成本大約等於實際承認的成本,即一起成長兩倍。我發現一個匹配平均花了約3.6uS,並且搜索結果花了約7.5uS。 –

回答