【问题标题】:Haskell: Delimit a string by chosen sub-strings and whitespaceHaskell:通过选择的子字符串和空格分隔字符串
【发布时间】:2010-11-28 02:16:23
【问题描述】:

我还是 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 上启发我 :-)

【问题讨论】:

    标签: haskell


    【解决方案1】:

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

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

    多么奇怪的类型啊!该列表用于与标准类型的解析器交互,但我很确定lex 总是返回 1 或 0 个元素(0 表示解析失败)。元组是(token-lexed, rest-of-input),所以lex 只提取一个令牌。因此,对整个字符串进行 lex 的一种简单方法是:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 感谢您的回答。然而,我希望有一种“纯粹”的简单方法,即没有其他库。哦,最好也没有单子(因为我还没有完全了解它们,哈哈)。
      • 是的,当您刚开始时,解析秒并不是很好。我发现编辑别人编写的解析器相当容易,但编写自己的解析器有一段时间超出了我的能力。需要对 monad 有一定的了解。
      • 很公平。值得考虑作为一种选择。如果您想要其他不是单子的东西,您可能必须使用自定义选项。
      【解决方案3】:

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

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

      【讨论】:

      • 哦 - 刚刚看到我想得不长:单词不会将“y:=”拆分为“y”,“:=”,因此您需要编写您的拥有简单的解析器(也许借助单词 :P)或使用解析器(无论如何这是一个很好的选择)。
      • 另外,问题中已经提到了“单词”的使用;)
      • Wonderfull - 我应该开始使用我的 cmets 迷失方向作为去睡觉的指标..
      猜你喜欢
      • 2018-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 1970-01-01
      • 2016-04-28
      • 2018-07-06
      相关资源
      最近更新 更多