截至目前,我正在使用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之外的其他东西才能实现这一目标,而我的主要问题是如何制作它以便它只在每行的第一个空格处分割。
答案 0 :(得分:1)
TextIO.inputAll
没问题。在这种情况下,似乎String.tokens
不适合这项工作。就个人而言,我只想编写自己的函数,使用String.explode
和String.implode
将string
转换为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")]
答案 1 :(得分: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