从 lisp 中的字符串解析数字

标签 parsing text lisp common-lisp

这是一个简短的问题:
输入:字符串列表,每个字符串包含数字
("3.4 5.4 1.2 6.4""7.8 5.6 4.3""1.2 3.2 5.4")

输出:一个数字列表
(3.4 5.4 1.2 6.4 7.8 5.6 4.3 1.2 3.2 5.4)

这是我的编码尝试:

(defun parse-string-to-float (line &optional (start 0))
  "Parses a list of floats out of a given string"
  (if (equalp "" line)
    nil
    (let ((num (multiple-value-list (read-from-string (subseq line start)))))
      (if (null (first num))
        nil
        (cons (first num) (parse-string-to-float (subseq line (+ start (second num)))))))))

(defvar *data* (list "  3.4 5.4 1.2 6.4" "7.8 5.6 4.3" "1.2 3.2 5.4"))

(setf *data* (format nil "~{~a ~}" *data*))

(print (parse-string-to-float *data*))

===> (3.4 5.4 1.2 6.4 7.8 5.6 4.3 1.2 3.2 5.4)

但是,对于相当大的数据集,这是一个缓慢的过程。我猜递归不是尽可能的紧凑,我正在做一些不必要的事情。有任何想法吗?

此外,这个宏伟的项目涉及获取一个输入文件,该文件包含由关键字分隔的各种数据部分。示例 -

%FLAG START_COORDS
1   2   5   8   10   12  
%FLAG END_COORDS  
3   7   3   23   9   26
%FLAG NAMES
ct  re  ct  cg  kl   ct

等等... 我正在尝试使用 %FLAG 后面的关键字作为键来解析哈希表,并将值存储为数字或字符串列表,具体取决于我正在解析的特定关键字。对于已经完成此类工作的图书馆有什么想法,或者用 lisp 解决这个问题的简单方法吗?

最佳答案

这不是您希望以递归方式开始的任务。相反,请使用 LOOPCOLLECT 子句。例如:

(defun parse-string-to-floats (line)
  (loop
    :with n := (length line)
    :for pos := 0 :then chars
    :while (< pos n)
    :for (float chars) := (multiple-value-list
            (read-from-string line nil nil :start pos))
    :collect float))

此外,您可能需要考虑使用 WITH-INPUT-FROM-STRING 而不是 READ-FROM-STRING,这会使事情变得更加简单。

(defun parse-string-to-float (line)
  (with-input-from-string (s line)
    (loop
      :for num := (read s nil nil)
      :while num
      :collect num)))

至于性能,您可能需要做一些分析,并确保您确实在编译您的函数。

编辑 添加:您确实需要注意的一件事是,如果您不确定字符串的来源,读者可能会引入安全漏洞。有一个读取宏,#.,当它从字符串中读取时,它可以允许计算它后面的任意代码。保护自己的最好方法是绑定(bind) *READ-EVAL*变量为 NIL,如果遇到 #.,这将使阅读器发出错误信号。或者,您可以使用一个专门的库 Rainer Joswig mentions in his answer .

关于从 lisp 中的字符串解析数字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1495475/

相关文章:

django - 解析django测试结果

javascript - Jquery 替换 br 标签

c - 为客户 C 编程分配点

emacs - 在 "Slime"(最新版本)中设置 "emacs"时,我如何告诉它更快地加载 swank?

javascript - 带有逻辑或的奇怪 JavaScript 赋值

java - 从字符串数组中解析 int 时出现 ArrayIndexOutOfBound

javascript - 解析 React 中字符串内的嵌套 HTML?

css - 如何使用 CSS 为具有相同类的特定按钮替换文本

list - 每次递增都会创建一个子列表的 Lisp 程序

open-source - 寻找迷你语言的 (c)lisp 示例,即 DSL