Regex 公共Lisp将类正则表达式模式应用于PLIST中的键

Regex 公共Lisp将类正则表达式模式应用于PLIST中的键,regex,lisp,common-lisp,plist,Regex,Lisp,Common Lisp,Plist,我想知道是否有可能将类似正则表达式的模式匹配应用于plist中的键 也就是说,假设我们有这样一个列表(:input1 1:input22:input33:output110:output220…:在这里展开“字符串”) 我需要编写的代码大致如下: “如果列表的键中有:expand和(:input*或:output*),则执行某些操作并返回:expand和(:output*或:input*)” 显然,这可以通过cond来实现,但我看不到一个清晰的方式来优雅地编写这篇文章。因此,我考虑可能对键使用类

我想知道是否有可能将类似正则表达式的模式匹配应用于plist中的键

也就是说,假设我们有这样一个列表
(:input1 1:input22:input33:output110:output220…:在这里展开“字符串”)

我需要编写的代码大致如下:

“如果列表的键中有
:expand
和(
:input*
:output*
),则执行某些操作并返回
:expand
和(
:output*
:input*
)”

显然,这可以通过
cond
来实现,但我看不到一个清晰的方式来优雅地编写这篇文章。因此,我考虑可能对键使用类似Regex的模式,并基于该模式搜索的结果返回

欢迎提出任何建议。

规范您的输入 算法简化问题其余部分的第一步可能是以结构化的方式规范化输入,而不是在符号名称中保留相同的信息。我正在将键从符号转换为符号或列表。您还可以定义自己的类来表示输入和输出,并编写适用于这两者的通用函数

(defun normalize-key (key)
  (or (cl-ppcre:register-groups-bind (symbol number)
          ("^(\\w+)(\\d+)$" (symbol-name key))
        (list (intern symbol "KEYWORD")
              (parse-integer number)))
      key))

(defun test-normalize ()
  (assert (eq (normalize-key :expand) :expand))
  (assert (equal (normalize-key :input1) '(:input 1))))
上面的
规范化键
:inputN
解构为一个列表
(:input N)
,并将
N
解析为一个数字。使用上述函数,可以规范化整个列表(如果需要,也可以递归地对值进行规范化):


从那里,您应该能够更轻松地实现您的逻辑

这看起来很像XY问题。如果使用属性树会怎么样:与
:input
关联的值将是另一个plist,等等?我无法控制原始结构。我修改此代码是为了在遇到特定场景时抛出警告。除非您建议我遍历子例程中的原始列表并将其修改为树?引用的部分,即您的规范,对我来说有点不清楚:如果同时存在输入和输出呢?如果列表包含其他不相关的键怎么办?也许你可以加上一两个例子。您可以随时将列表预处理为更合适的数据结构,这取决于您的许多需要。例如,您可以将键的格式设置为
(:input n)
,而不是符号。符号的问题在于,您回到了非结构化领域,在那里,唯一的选择是每次需要执行操作时解析符号名称(“严格类型”方法),而不是一次。
(defun normalize-plist (plist)
  (loop
    for (key value) on plist by #'cddr
    collect (normalize-key key)
    collect value))

(normalize-plist
 '(:input1 1 :input2 2 :input3 3 :output1 10 :output2 20 :expand "string here"))

=> ((:INPUT 1) 1
    (:INPUT 2) 2
    (:INPUT 3) 3
    (:OUTPUT 1) 10
    (:OUTPUT 2) 20
    :EXPAND "string here")