string - Haskell:如何将 "\\0"转换为 "\0"?

标签 string haskell escaping

Haskell 有多个 string literals使用\转义序列。例如 \n\t\NUL

如果我有字符串文字:

let s = "Newline: \\n Tab: \\t"

如何定义函数 escape::String -> String 将上述字符串转换为:

"Newline: \n Tab: \t"

与所有其他字符串文字转义序列相同。

我可以使用准引用和模板 Haskell,但不知道如何使用它们来实现结果。有什么指点吗?

<小时/>

更新:我刚刚找到了 Text.ParserCombinators.ReadP包含在基础库中的模块。它支持readLitChar :: ReadS Char Data.Char 中的函数可以满足我的要求,但我不知道如何使用 ReadP 模块。我尝试了以下方法并且有效:

escape2 [] = []
escape2 xs = case readLitChar xs of
    [] -> []
    [(a, b)] -> a : escape2 b

但这可能不是使用 ReadP 模块的正确方法。谁能提供一些指导吗?

另一更新:谢谢大家。我的最终功能如下。我认为还不错。

import Text.ParserCombinators.ReadP
import Text.Read.Lex

escape xs 
    | []      <- r = []
    | [(a,_)] <- r = a
    where r = readP_to_S (manyTill lexChar eof) xs 

最佳答案

您无需执行任何操作。当您输入字符串文字时

let s = "Newline: \\n Tab: \\t"

您可以检查它是否是您想要的:

Prelude> putStrLn s
Newline: \n Tab: \t
Prelude> length s
19

如果你只是向 ghci 询问 s 的值,你会得到其他东西,

Prelude> s
"Newline: \\n Tab: \\t"

显然它在背后做一些转义格式,并且还显示引号。如果您调用 showprint,您还会得到其他答案:

Prelude> show s
"\"Newline: \\\\n Tab: \\\\t\""
Prelude> print s
"Newline: \\n Tab: \\t"

这是因为 show 用于序列化值,因此当您 show 一个字符串时,您不会得到原始字符串,而是会得到一个序列化字符串,该字符串可以被解析为原始字符串。 show s 的结果实际上是由 print s 显示的(print 定义为 putStrLn . show)。当你在 ghci 中 show s 时,你会得到一个更奇怪的答案;这里 ghci 正在格式化由 show 序列化的字符。

tl;dr - 始终使用 putStrLn 来查看 ghci 中字符串的值。

编辑:我刚刚意识到也许你想转换文字值

Newline: \n Tab: \t

进入实际的控制序列。最简单的方法可能是将其放在引号中并使用 read:

Prelude> let s' = '"' : s ++ "\""
Prelude> read s' :: String
"Newline: \n Tab: \t"
Prelude> putStrLn (read s')
Newline: 
 Tab:   

编辑2:使用readLitChar的示例,这与Chris的答案非常接近,除了readLitChar:

strParser :: ReadP String
strParser = do
  str <- many (readS_to_P readLitChar)
  eof
  return str

然后你用readP_to_S运行它,它会给你一个匹配解析的列表(不应该有超过一个匹配,但是可能没有任何匹配,所以你应该检查一个空的列表。)

> putStrLn . fst . head $ readP_to_S strParser s
Newline:
Tab:    
>

关于string - Haskell:如何将 "\\0"转换为 "\0"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7171265/

相关文章:

c# - 检查字符串是否包含在数组中

haskell - 当存在一些递归情况时保持内联的潜力

list - Haskell 中的这个列表排列实现究竟做了什么?

css - 我应该如何为 CSS 转义图像 URL?

vb.net - 在VB中的字符串中使用左双引号

hibernate - hibernate 查询转义(来自Grails的GORM)-再次

python - 从句子中输出一个列表并计算每个单词的字符数

java - Android - 替换字符串中的数据

python - 仅拆分字符串中的长单词

haskell - Haskell 中 PETSc FFI 的库设计