【问题标题】:SML splitting string on first spaceSML 在第一个空格上拆分字符串
【发布时间】:2017-09-03 11:44:58
【问题描述】:

截至目前,我正在使用 inputAll 读取整个输入文件,然后使用 String.tokens 在每次出现空格时拆分每个单词。

val file = TextIO.openIn input
val _input = TextIO.inputAll file
val _ = TextIO.closeIn file
String.tokens Char.isSpace _input

例如)“红蓝绿”看起来像这样

["red", "blue", "green"]

但是,现在我想将其更改为仅在每行第一次出现空格字符时拆分字符串。

例如)“红蓝绿”应该看起来像

["red", "blue green"]

我觉得我需要使用 inputAll 以外的其他方法来完成此操作,我的主要问题是如何做到这一点,以便它只在每行的第一个空格处拆分。

【问题讨论】:

    标签: sml smlnj


    【解决方案1】:

    这里是另一个使用Substring的函数dropl、dropr和splitl的选项 还有TextIO.inputLine

      structure SS = Substring;
      structure C = Char;
      structure TIO = TextIO;
    
      fun splitFile(arg) =
      let val file = TIO.openIn arg
          val line = TIO.inputLine file;
          fun trimWs ss = (SS.dropl (C.isSpace) (SS.dropr (C.isSpace) ss));
          fun splitLine(SOME str) acc =
            let val (l, r) = SS.splitl (not o C.isSpace) (SS.full str);
                val (l, r) = (trimWs l, trimWs r);
             in if SS.size l + SS.size r = 0
                   then splitLine (TIO.inputLine file) acc
                   else (SS.string l, SS.string r)::splitLine (TIO.inputLine file) acc
            end
            | splitLine (NONE) acc = acc;
          val result = splitLine line [];
          val _ = TextIO.closeIn file
       in result end
    

    【讨论】:

      【解决方案2】:

      TextIO.inputAll 很好。在这种情况下,String.tokens 似乎不是该工作的正确工具。我个人只会编写自己的函数,使用String.explodeString.implodestring 转换为char list/从char list

      fun splitCharsFirstSpace cs =
        case cs of
          [] => ([], [])
        | c :: cs' =>
            if Char.isSpace c then ([], cs')
            else let val (l, r) = splitCharsFirstSpace cs'
                 in (c :: l, r)
                 end
      
      fun splitFirstSpace s =
        let
          val (l, r) = splitCharsFirstSpace (String.explode s)
        in
          (String.implode l, String.implode r)
        end
      

      在上下文中,您可以按如下方式使用它。

      val file = TextIO.openIn input
      val contents = TextIO.inputAll file
      val _ = TextIO.closeIn file
      val lines = String.tokens (fn c => c = #"\n") contents
      val lines' = List.map splitFirstSpace lines
      

      例如,如果您的输入文件是这样的:

      red blue green
      yellow orange purple pink
      

      那么lines' 将如下所示:

      [("red", "blue green"), ("yellow", "orange purple pink")]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-08
        • 2013-04-19
        • 2012-05-10
        • 2012-05-03
        • 1970-01-01
        • 2015-11-26
        相关资源
        最近更新 更多