String 是否存在公共Lisp的反向';s格式?
我有一个问题困扰了我一段时间。通用LispString 是否存在公共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) 您是否知道有任何此类
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。我发现了。