简体   繁体   English

Common Lisp将类似Regex的模式应用于PLIST中的键

[英]Common Lisp Applying Regex-like Patterns to Keys in PLIST

I am wondering if it is possible to apply Regex-like pattern matching to keys in a plist. 我想知道是否可以将类似Regex的模式匹配应用于plist中的键。

That is, suppose we have a list like this (:input1 1 :input2 2 :input3 3 :output1 10 :output2 20 ... :expand "string here") 也就是说,假设我们有一个这样的列表(:input1 1 :input2 2 :input3 3 :output1 10 :output2 20 ... :expand "string here")

The code I need to write is something along the lines of: 我需要编写的代码是:

"If there is :expand and ( :input* or :output* ) in the list's keys, then do something and also return the :expand and ( :output* or :input* )". “如果列表的键中有:expand和( :input*:output* ),则执行某些操作并返回:expand和( :output*:input* )”。

Obviously, this can be accomplished via cond but I do not see a clear way to write this elegantly. 显然,这可以通过cond完成,但我没有看到一个明确的方式来优雅地写这个。 Hence, I thought of possibly using a Regex-like pattern on keys and basing the return on the results from that pattern search. 因此,我想到可能在键上使用类似Regex的模式,并根据模式搜索的结果返回。

Any suggestions are appreciated. 任何建议表示赞赏。

Normalize your input 标准化您的输入

A possible first step for your algorithm that will simplify the rest of your problem is to normalize your input in a way that keep the same information in a structured way, instead of inside symbol's names. 算法的第一步可以简化问题的其余部分,即以一种以结构化方式保留相同信息的方式规范化输入,而不是在符号内部。 I am converting keys from symbols to either symbols or lists. 我正在将符号转换为符号或列表。 You could also define your own class which represents inputs and outputs, and write generic functions that works for both. 您还可以定义自己的类来表示输入和输出,并编写适用于这两者的泛型函数。

(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))))

The above normalize-key deconstructs :inputN into a list (:input N) , with N parsed as a number. 上面的normalize-key解构:inputN (:input N)到列表(:input N)N解析为数字。 Using the above function, you can normalize the whole list (you could do that recursively too for values, if you need it): 使用上面的函数,您可以规范化整个列表(如果需要,您也可以递归地对值进行操作):

(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")

From there, you should be able to implement your logic more easily. 从那里,您应该能够更轻松地实现您的逻辑。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM