我在F#中编写了一个函数来解析整数列表。我通过创建一个函数来测试它,该函数应该打印出每个列表中的所有值,从每个列表的末尾开始一个新行。这些值都是正确的,但没有打印新的线条。我首先从命令提示符中获取输入然后解析它来测试它。
以下是我的解析功能:
let rec parseIntList (str : string) : int list =
let capture = Regex.Match(str, "\d+(;|])")
if capture = Match.Empty then [] else
let init : int = capture.Index
let fin : int = init + capture.Length
(int str.[init..(fin - 2)]) :: (parseIntList str.[fin..])
let rec parse2dIntList (str : string) : int list list =
let capture = Regex.Match(str, "\[.{3,}](;|])")
if capture = Match.Empty then [] else
let init : int = capture.Index
let fin : int = init + capture.Length
(parseIntList str.[init..(fin - 2)]) :: (parse2dIntList str.[fin..])
在我开展这项工作时,根本没有改变。
以下是我的打印功能:
let rec printList (list : int list) : unit =
for i in list do
printf "%i " i
printfn "%s" "" //printfn "" and printf "\n" didn't work either
let rec print2dList (list : int list list) : unit =
match list with
| [] -> ()
| (x :: xs) -> printList x; print2dList xs
let _ = while true do
let input = System.Console.ReadLine()
let output = parse2dIntList input
if output = [] then printfn "Please give valid input"
else print2dList output
上面的代码生成了正确的值,但没有打印新行。但是,当我像这样测试时,
let _ = while true do
print2dList [[1;2;3];[4;5;6];[7;8;9]]
多次使用新行打印正确的值。最后的结论是我的解析功能是将2d列表解析为1d列表。但我非常有信心,因为我已经设置了这些功能的方式,如果这是真的,就会出现类型错误。
我的正则表达式是不正确的?我试图转义结束方括号,即使用\]
而不是]
,但它只是搞砸了所有内容。
答案 0 :(得分:4)
如果您运行parse2dIntList [[1;2;3];[4;5;6];[7;8;9]]
,您会发现它已经无效,它会返回一个单位列表。
因此,您可以从问题中删除所有打印内容,因为很明显问题出在解析中。在调试过程中包含打印功能只会增加噪音并使其更加复杂。
现在,如果您使用在线正则表达式测试程序,您将看到模式\[.{3,}](;|])
未捕获子列表。
尝试调整它,例如,如果您使用类似.+?(?=\])\].
的内容,它将起作用:
let rec parse2dIntList (str : string) : int list list =
let capture = Regex.Match(str, ".+?(?=\])\].")
if capture = Match.Empty then [] else
let init : int = capture.Index
let fin : int = init + capture.Length
(parseIntList str.[init..(fin - 2)]) :: (parse2dIntList str.[fin..])
测试
parse2dIntList "[[1;2;3];[4;5;6];[7;8;9]]" ;;
val it : int list list = [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]]
当然,如果你尝试所有的印刷品,它现在都可以使用。