Проблема довольно проста: мне нужно заменить все вхождения "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) . Более того, это может иметь неожиданный результат замены подстроки результата предыдущей замены.