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