Haskell:通过选择的子字符串和空格分隔字符串

时间:2010-11-28 02:16:24

标签: haskell

对Haskell来说还是新手,如果对此有明显的答案,请道歉...


我想创建一个函数来分割所有后面的字符串列表,即[String]:

["int x = 1", "y := x + 123"]
["int   x=   1", "y:=   x+123"] 
["int x=1", "y:=x+123"] 

全部进入相同的字符串,即[[String]]:

[["int", "x", "=", "1"], ["y", ":=", "x", "+", "123"]]



您可以使用map words.lines作为第一个[String]。

但我不知道任何真正的方法也要考虑其他方法 - 您将使用各种子字符串"="":=""+"等来打破主弦。



感谢您花时间在Haskell上启发我: - )

3 个答案:

答案 0 :(得分:7)

Prelude带有一个鲜为人知的方便函数lex,它是Haskell表达式的词法分析器。这些符合您需要的形式。

lex :: String -> [(String,String)]

虽然多么奇怪!该列表用于与标准类型的解析器连接,但我非常确定lex总是返回1或0个元素(0表示解析失败)。元组为(token-lexed, rest-of-input),因此lex仅提取一个标记。因此,整个字符串的简单方法是:

lexStr :: String -> [String]
lexStr "" = []
lexStr s = 
    case lex s of
        [(tok,rest)] -> tok : lexStr rest
        []           -> error "Failed lex"

为了安抚学生,这段代码很糟糕。显式调用error而不是使用Maybe返回合理错误,假设lex仅返回1或0个元素,等等。执行此操作的代码长度大致相同,但是显然更抽象,所以我饶了你的初学者眼睛。

答案 1 :(得分:3)

我会看看parsec并构建一个简单的语法来解析你的字符串。

答案 2 :(得分:0)

如何使用单词。) words :: String -> [String] 并且单词不会关心白色空间..

words "Hello World"
= words "Hello     World"
= ["Hello", "World"]