2011-11-14 36 views
3

我需要製作一個subRegex的函數版本,它與Text.Regex.PCRE一起使用。PCRE版本subRegex

Text.Regex模塊中提供的的subRegex版本this

{- | Replaces every occurance of the given regexp with the replacement string. 

In the replacement string, @\"\\1\"@ refers to the first substring; 
@\"\\2\"@ to the second, etc; and @\"\\0\"@ to the entire match. 
@\"\\\\\\\\\"@ will insert a literal backslash. 

This does not advance if the regex matches an empty string. This 
misfeature is here to match the behavior of the the original 
Text.Regex API. 
-} 

subRegex :: Regex       --^Search pattern 
     -> String       --^Input string 
     -> String       --^Replacement text 
     -> String       --^Output string 
subRegex _ "" _ = "" 
subRegex regexp inp repl = 
    let compile _i str [] = \ _m -> (str++) 
     compile i str (("\\",(off,len)):rest) = 
     let i' = off+len 
      pre = take (off-i) str 
      str' = drop (i'-i) str 
     in if null str' then \ _m -> (pre ++) . ('\\':) 
      else \ m -> (pre ++) . ('\\' :) . compile i' str' rest m 
     compile i str ((xstr,(off,len)):rest) = 
     let i' = off+len 
      pre = take (off-i) str 
      str' = drop (i'-i) str 
      x = read xstr 
     in if null str' then \ m -> (pre++) . ((fst (m!x))++) 
      else \ m -> (pre++) . ((fst (m!x))++) . compile i' str' rest m 
     compiled :: MatchText String -> String -> String 
     compiled = compile 0 repl findrefs where 
     -- bre matches a backslash then capture either a backslash or some digits 
     bre = mkRegex "\\\\(\\\\|[0-9]+)" 
     findrefs = map (\m -> (fst (m!1),snd (m!0))) (matchAllText bre repl) 
     go _i str [] = str 
     go i str (m:ms) = 
     let (_,(off,len)) = m!0 
      i' = off+len 
      pre = take (off-i) str 
      str' = drop (i'-i) str 
     in if null str' then pre ++ (compiled m "") 
      else pre ++ (compiled m (go i' str' ms)) 
    in go 0 inp (matchAllText regexp inp) 

當我運行這個進口Text.Regex.PCRE,我得到

不在範圍內: 'mkRegex'

在RegexLike模塊中有一個叫做makeRegex的函數但它有不同的類型,這是我卡住的地方。

編輯 - 解決方案

創建新mkRegex功能,像這樣:

-- | Makes a regular expression with the default options 
mkRegex :: String -> Regex 
mkRegex s = makeRegexOpts opt defaultExecOpt s 
    where opt = (defaultCompOpt + compCaseless) -- or other options 
+0

你知道爲什麼這次沒有補丁嗎? –

回答

2

mkRegexText.Regex定義的正則表達式-compat的包。你可以試着複製它的源代碼。如果它在沒有改變的情況下完全運行,我會感到驚訝,但也許不需要太多。

+0

謝謝你,這麼簡單,但它稍作修改。 –