简体   繁体   English

从 Haskell 中的字符串替换子字符串

[英]Replace a substring from a string in Haskell

I have the following string "not really//" and I want to write a function that replaces every two slashes "//" with two dots ".."我有以下字符串"not really//" ,我想编写一个函数,用两个点".."替换每两个斜杠"//" ".."

I thought about using map, but then I would iterate through characters and can't know if a slash is going to be followed by another or not.我想过使用地图,但后来我会遍历字符并且不知道斜线后面是否会跟另一个斜线。 Any clue how this can be done?任何线索如何做到这一点? (without regex) (没有正则表达式)

We can use the replace :: Text -> Text -> Text -> Text function of the Data.Text function.我们可以使用Data.Text函数的replace :: Text -> Text -> Text -> Text Data.Text replace :: Text -> Text -> Text -> Text Data.Text replace :: Text -> Text -> Text -> Text Data.Text replace :: Text -> Text -> Text -> Text函数。 For example:例如:

Prelude Data.Text> replace "//" ".." "not really//"
"not really.."

Here we work however on Text s.然而,我们在这里处理Text s。 If that is a problem, we can also use pack :: String -> Text and unpack :: Text -> String to convert between String and Text .如果这是一个问题,我们还可以使用pack :: String -> Textunpack :: Text -> StringStringText之间进行转换。 So we can define a function with:所以我们可以定义一个函数:

{-# LANGUAGE OverloadedStrings #-}

import Data.Text(pack, unpack, replace)

replacedoubleslash :: String -> String
replacedoubleslash = unpack . replace "//" ".." . pack

But usually for efficient string processing - both in terms of speed and memory - using Text is better than working with String s.但通常对于高效的字符串处理 - 无论是在速度还是内存方面 - 使用Text都比使用String更好。

Explicit recursion looks fine here:显式递归在这里看起来不错:

replace :: String -> String
replace ('/':'/':xs) = '.' : '.' : replace xs
replace (x:xs)       = x : replace xs
replace ""           = ""

This does not scale to long patterns, but for replacing "//" it should work fine.这不会扩展到长模式,但是对于替换“//”它应该可以正常工作。

If you don't want to use any package, this is what I've come with:如果你不想使用任何包,这就是我带来的:

isHead':: String -> String -> String -> Bool
isHead' str [] ret = True
isHead' [] key  ret = False
isHead' (x:xs) (x':xs') ret = (x == x') && isHead' xs xs' ret

isHead:: String -> String ->  Bool
isHead  key str= isHead' str key key

remouveXelem:: Int ->[a] -> [a]
remouveXelem i a | i <= 0 = a
remouveXelem _ [] = [] 
remouveXelem i (x:xs) = remouveXelem (i - 1) xs  

replace :: String -> String -> String -> String
replace ori new [] = []
replace ori new s = if isHead ori s then
    new ++ replace ori new (remouveXelem (length ori) s)
    else head s : replace ori new (tail s)

replace "i" "a" "il etait une fois" => "al etaat une foas"替换“i”“a”“il etait une fois”=>“al etaat une foas”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM