Подтвердить что ты не робот

Замена регулярного выражения haskell

Несмотря на смехотворно большое количество двигателей для согласования регулярных выражений для Haskell, единственное, что я могу найти, это заменить Text.Regex, который, несмотря на приличный, не хватает нескольких вещей, которые мне нравятся из pcre. Существуют ли какие-либо пакеты на основе pcre, которые будут делать подстановку, или я придерживаюсь этого?

4b9b3361

Ответ 1

Регулярное выражение API в regex-base является общим для контейнера символов, которые должны совпадать. Выполнение какого-либо сплайсинга в целом для реализации замещения было бы очень трудно сделать эффективным. Я не хотел предлагать дрянной родовой режим.

Написание маленькой функции для выполнения подстановки точно так, как вы хотите, это просто лучшая идея, и ее можно записать в соответствии с вашим контейнером.

Ответ 2

Я не думаю, что "просто сворачивайте свои собственные" - это разумный ответ людям, которые пытаются выполнить настоящую работу, в области, где каждый другой современный язык имеет тривиальный способ сделать это. Включая схему. Итак, некоторые реальные ресурсы; мой код из проекта, где я пытался заменить "qql foo bar baz qq" на текст, основанный на вызове функции на вещи внутри квадратных скобок qq, потому что причины.

Лучший вариант: pcre-heavy:

      let newBody = gsub [re|\s(qq[a-z]+)\s(.*?)\sqq\s|] (unWikiReplacer2 titles) body in do
[snip]
unWikiReplacer2 :: [String] -> String -> [String] -> String
unWikiReplacer2 titles match subList = case length subList > 0 of
        True -> " --" ++ subList!!1 ++ "-- "
        False -> match

Обратите внимание, что pcre-heavy напрямую поддерживает функциональную замену, с любым тип строки. Так приятно.

Другая опция: pcre-light с небольшой функцией, которая работает, но не совсем производительный:

    let newBody = replaceAllPCRE "\\s(qq[a-z]+)\\s(.*?)\\sqq\\s" (unWikiReplacer titles) body in do
[snip]
unWikiReplacer :: [String] -> (PCRE.MatchResult String) -> String
unWikiReplacer titles mr = case length subList > 0 of
        True -> " --" ++ subList!!1 ++ "-- "
        False -> PCRE.mrMatch mr
    where
        subList = PCRE.mrSubList mr

-- A very simple, very dumb "replace all instances of this regex
-- with the results of this function" function.  Relies on the
-- MatchResult return type.
--
-- https://github.com/erantapaa/haskell-regexp-examples/blob/master/RegexExamples.hs
-- was very helpful to me in constructing this
--
-- I also used
-- https://github.com/jaspervdj/hakyll/blob/ea7d97498275a23fbda06e168904ee261f29594e/src/Hakyll/Core/Util/String.hs
replaceAllPCRE :: String              -- ^ Pattern
           -> ((PCRE.MatchResult String) -> String)  -- ^ Replacement (called on capture)
           -> String              -- ^ Source string
           -> String              -- ^ Result
replaceAllPCRE pattern f source =
    if (source PCRE.=~ pattern) == True then
      replaceAllPCRE pattern f newStr
    else
      source
    where
        mr = (source PCRE.=~ pattern)
        newStr = (PCRE.mrBefore mr) ++ (f mr) ++ (PCRE.mrAfter mr)

Кто-то еще исправит: http://0xfe.blogspot.com/2010/09/regex-substitution-in-haskell.html

Другой, на этот раз встроенный в большую библиотеку: https://github.com/jaspervdj/hakyll/blob/master/src/Hakyll/Core/Util/String.hs

Другой пакет для этой цели: https://hackage.haskell.org/package/pcre-utils