String 是否存在公共Lisp的反向';s格式?

String 是否存在公共Lisp的反向';s格式?,string,lisp,common-lisp,string-parsing,String,Lisp,Common Lisp,String Parsing,我有一个问题困扰了我一段时间。通用Lispformat函数是否可逆(至少在某种程度上),因为format字符串可用于从format的输出检索原始参数?我知道映射不是一对一的(一个例子是~@:(~a~),它将输入转换为大写,并且是不可逆的),因此必然会丢失一些信息。我所想的恰恰是字符串解析中正则表达式的替代方法。例如,我希望能够写: (destructure-format t "[~{~a~^, ~}]" "[0, 1, 2]") 并得到回应: => (0 1 2) 您是否知道有任何此类

我有一个问题困扰了我一段时间。通用Lisp
format
函数是否可逆(至少在某种程度上),因为format字符串可用于从
format
的输出检索原始参数?我知道映射不是一对一的(一个例子是
~@:(~a~)
,它将输入转换为大写,并且是不可逆的),因此必然会丢失一些信息。我所想的恰恰是字符串解析中正则表达式的替代方法。例如,我希望能够写:

(destructure-format t "[~{~a~^, ~}]" "[0, 1, 2]")
并得到回应:

=> (0 1 2)
您是否知道有任何此类尝试或论文讨论过类似的方法?

标准中没有任何内容 标准中没有这样的东西<代码>格式表达式中没有足够的信息使其在任何实际意义上都有用。对于几乎所有不绑定的内容,有一些方式很难读回输出。在您给出的示例中,使用列表格式

(destructure-format t "[~{~a~^, ~}]" "[0, 1, 2]")
任何解决方案都必须检查format指令。那么,它可以毫不含糊地观察到什么?字符串中的第一个字符必须是
\[
,最后一个字符必须是
\]
,并且字符串中出现的一些
“,”
将由
~a
生成的输出分开。那么,会出现什么歧义呢?任何会导致在输出中写入
,“
的内容。例如:

CL-USER> (format t "[~{~a~^, ~}]" '(|, | 2 3))
[, , 2, 3]
NIL
CL-USER> (format t "[~{~a~^, ~}]" '(|, | | ,|))
[, ,  ,]
NIL
CL-USER> (format t "[~{~a~^, ~}]" '(|, | | ,| |,|))
[, ,  ,, ,]
NIL
CL-USER> (format t "[~{~a~^, ~}]" '(|, | | ,| #\,))
[, ,  ,, ,]
NIL
第三方图书馆 虽然库建议与堆栈溢出无关,但这个问题并不是从一开始就提出的,但在看到建议使用外部函数调用C的
scanf
后,我在CLiki上快速搜索了scanf,并找到了(并重新阅读了注释),其描述如下:

scanf()的公共Lisp等效项

comp.lang.lisp上的一个(相对)常见问题是“什么是 等效于scanf()?”。通常的答案是“没有一个, 因为要想知道应该发生什么太难了”。这是公平的 够了

然而,有一年,克里斯托弗在考试中感到无聊,所以他写道 ,它可以做你想做的事

应该指出的是,目前该计划的行为 是不明确的,在更多的意义上,不仅仅是符号的撞击 “CL”包。最好能看到一个规范 为它的行为而出现,这样我就没有借口当人们 说是马车

其他选择 因为你最终会问“这可能匹配的方式有哪些,你本质上是在问正则表达式加上格式可能带来的额外内容

我所想的恰恰是一个常规的替代品 用于字符串解析的表达式


如果您正在寻找正则表达式,那么正则表达式非常适合。如果您正在寻找非正则表达式的解析,那么您可能想要编写一个真正的解析器。第一次可能会让人望而生畏,但在那之后,它会变得容易得多,而Common Lisp使其相对轻松。甚至还有解析器类可用的语法库。另一方面,如果您正在寻找序列化和反序列化,则通用的Lisp读写器会使s表达式成为一个很好且简单的选择。

如果您想要基于格式字符串的语法分析,但不需要
格式的高级功能,则可以通过FFI使用C的
scanf
函数.以下是使用CFFI执行此操作的示例:

(with-foreign-strings ((input "[0, 1, 2]") (format "[%d, %d, %d]"))
  (with-foreign-objects ((a :int) (b :int) (c :int))
    (foreign-funcall "sscanf" :pointer input :pointer format
                     :pointer a :pointer b :pointer c)
    (loop for x in (list a b c) collect (mem-ref x :int))))

胡。和的组合怎么样?如果你需要序列化数据,这就是s表达式的用途。核心语言中没有任何东西,可以允许你在这里提到的那种字符串模式匹配。当然,你可以使用。是的,现在我看到了,这看起来是一件合理的事情。谢谢!-但它是k这是一个笑话/黑客。谢谢,@Xach。我一定会看一看。谢谢,@Joshua。我想我迟早会倾向于写一个解析器:)。你知道关于这个主题有什么好的简明指南吗?@WojciechGac Stack Overflow不是一个推荐库/工具的好地方,但你可能会在下面的网站上找到一些实用工具。至于理论和技术,很多人都喜欢。这个答案让我想在CLiki上搜索scanf。我发现了。