List LISP查找最后一对括号
我编写的函数必须返回}的位置,该位置对应于它从一开始找到的{的第一个匹配项(我不寻找}的最后一个匹配项)。 例如,给定这种JSON类型的结构化字符串List LISP查找最后一对括号,list,lisp,common-lisp,List,Lisp,Common Lisp,我编写的函数必须返回}的位置,该位置对应于它从一开始找到的{的第一个匹配项(我不寻找}的最后一个匹配项)。 例如,给定这种JSON类型的结构化字符串 (成对的-b(强制“[{\'b\':{\'c\':[[1,{\'d\':1}],{\'e\':3}],“'g\':2},{\'a\':2}]”列表) 该功能应 返回子序列->之前的}(与字符串的第一个{成对),{\“a\”:2}”,但返回子序列->之前的位置,\“g\”:2}。。。 但是如果我试着 (paired-b (coerce "[ {\"a
(成对的-b(强制“[{\'b\':{\'c\':[[1,{\'d\':1}],{\'e\':3}],“'g\':2},{\'a\':2}]”列表)
该功能应
返回子序列->之前的}(与字符串的第一个{成对),{\“a\”:2}”,但返回子序列->之前的位置,\“g\”:2}。。。
但是如果我试着
(paired-b (coerce "[ {\"a\" : 1} , {\"b\" : 2} ]" 'list))
函数返回所需}的正确位置,即逗号之前的位置。
代码的哪一部分有错误?有没有其他方法来实现这样的功能
(defun paired-b (list)
(if (position #\{ list)
(if (< (position #\{ list) (position #\} list))
(if (eql (position #\{ list) (- (position #\} list) 1))
(position #\} list :start
(+ (position #\{ list)
(paired-b (subseq list (+ (position #\{ list) 1))) 1))
(position #\} list :start
(+ (position #\{ list)
(paired-b (subseq list (+ (position #\{ list) 1) 2))))) 0) 0))
打开=计数{,关闭=计数},位置=位置od索引
这段代码似乎可以工作,但在解析器内部,其他函数调用它,如果我解析长字符串,程序就会发生堆栈溢出。从那里查找第一个
{
.Loop,计算嵌套级别。当级别达到0时,您就找到了匹配项
(defun curly-positions (string)
"Looks for the first #\{ in `string', then finds the matching #\}.
Returns these positions as two values."
(let* ((open-position (position #\{ string :test #'char=))
(close-position (loop :for i :upfrom (1+ open-position)
:for c := (char string i)
:for level := 1
:then (case c
(#\{ (1+ level))
(#\} (1- level))
(t level))
:when (zerop level)
:do (return i))))
(values open-position
close-position))))
(not(null…)
是。
数字与eql
或=
比较,但与eq
不比较。多次(position#\somechar x)
是丑陋的。写(eql(…
)而不是(eql(
)。因此,通过一些工作,您可能最终实现这一点,但是:强制向量(字符串)你可以使用loop
和for over
或者干脆用aref
来代替。另外,要注意如何处理格式错误的输入。还要注意字符串中的{
(和\”
)。如果您的最终目标是解析,我建议您使用/修改库或使用流(例如,使用字符串输入的),只需编写一个完整的解析器,一次检查一个字符。
(defun curly-positions (string)
"Looks for the first #\{ in `string', then finds the matching #\}.
Returns these positions as two values."
(let* ((open-position (position #\{ string :test #'char=))
(close-position (loop :for i :upfrom (1+ open-position)
:for c := (char string i)
:for level := 1
:then (case c
(#\{ (1+ level))
(#\} (1- level))
(t level))
:when (zerop level)
:do (return i))))
(values open-position
close-position))))