2014-02-06 30 views
7

我試圖匹配正則表達式的所有出現,並得到索引作爲結果。從真實世界哈斯克爾的例子說,我可以做正則表達式的所有匹配的索引

string =~ regex :: [(Int, Int)] 

然而,由於正則表達式庫以來一直RWH的出版物更新了這個被打破。 (見All matches of regex in Haskell"=~" raise "No instance for (RegexContext Regex [Char] [String])")。什麼是正確的方法來做到這一點?

更新:

我發現matchAll這可能給我我想要的東西。不過,我不知道如何使用它。

回答

4

的關鍵在於使用matchAll創建regexs當使用類型註釋:: Regex

import Text.Regex 
import Text.Regex.Base 

re = makeRegex "[^aeiou]" :: Regex 
test = matchAll re "the quick brown fox" 

這將返回陣列的列表。要獲得的列表(偏移,長度)對,只存取每個陣列的第一個元素:

import Data.Array ((!)) 

matches = map (!0) $ matchAll re "the quick brown fox" 
-- [(0,1),(1,1),(3,1),(4,1),(7,1),(8,1),(9,1),(10,1),(11,1),(13,1),(14,1),(15,1),(16,1),(18,1)] 

要使用=~操作者,情況可能已經因爲RWH改變。您應該使用預定義類型MatchOffsetMatchLength和特殊類型構造AllMatches

import Text.Regex.Posix 

re = "[^aeiou]" 
text = "the quick brown fox" 

test1 = text =~ re :: Bool 
    -- True 

test2 = text =~ re :: String 
    -- "t" 

test3 = text =~ re :: (MatchOffset,MatchLength) 
    -- (0,1) 

test4 = text =~ re :: AllMatches [] (MatchOffset, MatchLength) 
    -- (not showable) 

test4' = getAllMatches $ (text =~ re :: AllMatches [] (MatchOffset, MatchLength)) 
    -- [(0,1),(1,1),(3,1),(4,1),(7,1),(8,1),(9,1),(10,1),(11,1),(13,1),(14,1),(15,1),(16,1),(18,1)] 

Text.Regex.Base.Context的文檔,詳細瞭解什麼情況下是可用的。

更新:我相信類型構造AllMatches被引入到解決引入的歧義時正則表達式有子表達式 - 如:

foo = "axx ayy" =~ "a(.)([^a])" 

test1 = getAllMatches $ (foo :: AllMatches [] (MatchOffset, MatchLength)) 
    -- [(0,3),(3,3)] 
    -- returns the locations of "axx" and "ayy" but no subexpression info 

test2 = foo :: MatchArray 
    -- array (0,2) [(0,(0,3)),(1,(1,1)),(2,(2,1))] 
    -- returns only the match with "axx" 

兩者都是從根本上抵消長度對的列表,但它們的含義不同的東西。

+0

「typecast :: Regex」不是類型轉換。沒有數據類型的運行時修改。這是一個類型註釋 – Squidly

+1

是的 - 這是描述它的更好方法。 – ErikR

相關問題