2011-11-14 9 views
3

subRegexのバージョンをText.Regex.PCREで動作させる必要があります。subRegexのPCREバージョン

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

mkRegexが正規表現-compatのパッケージにText.Regexで定義されています。そのソースをコピーしてみることもできます。私はそれが変更せずに完全に動作した場合私は驚くだろうが、おそらく多すぎる必要はありません。

+0

ありがとう、とてもシンプルですが、少し修正しても機能します。 –

関連する問題