Лучший способ замены подстроки в haskell

Проблема довольно проста: мне нужно заменить все вхождения "fooo" "и все его подстроки с" xyz ". В Java, например, я сделаю это так:

someString.replaceAll( "fooo|foo|fo", "xyz" )

, и это поможет. Но в Haskell я не нашел эффективного способа работы с регулярным выражением. Прежде всего, я прочитал это: http: //www.haskell. org / haskellwiki / Regular_expressions

Единственная библиотека, которая действительно имеет функцию replace , - это regex-posix, но ее производительность считается "очень низкой". И это недопустимо. Также я обнаружил, что эта функция replace по каким-либо причинам не соблюдает порядок заданных шаблонов, поэтому я получил следующий результат:

>replace "boo fooo boo" "xyz"
"boo xyzoo boo"

Другие серверные ВМ не предполагают такой функциональности.

Итак, я решил написать простой обходной путь:

replaceFoo input =
    helper input []
    where
        helper ('f':'o':'o':'o':xs) ys = helper xs ("zyx" ++ ys)
        helper ('f':'o':'o':xs) ys = helper xs ("zyx" ++ ys)
        helper ('f':'o':xs) ys = helper xs ("zyx" ++ ys)
        helper (x:xs) ys = helper xs (x:ys)
        helper [] ys = reverse ys

Хотя мне эта функция не нравится, она работает хорошо и быстро. Но пока я столкнулся с необходимостью добавить больше слов в этот заменитель, и мне больше не нравится идея расширения паттернов helper (я должен сказать, что на самом деле у меня в нем 4 слова в реальном приложении и это странно).

Я ' Буду рад, если кто-нибудь поможет мне с решением fast .


cebewee , спасибо за Data.String.Utils. Но я боюсь, что этот подход будет довольно медленным, если нужно заменить много слов («fooo» на «xyz», «foo» на «xyz», «fo» на «xyz», «bar» на «quux» и т. Д. ), потому что для того, чтобы это работало, мне понадобится foldr (\ str (from, to) -> replace from to str) input pair или что-то в этом роде, и это займет O (n * n) . Более того, это может иметь неожиданный результат замены подстроки результата предыдущей замены.

7
задан Community 23 May 2017 в 12:23
поделиться