2024 年 Clojure 状态调查! 中分享您的想法。

欢迎!有关如何使用本网站的更多信息,请参阅关于 页面。

0
Spec

我有一个字符序列,并尝试使用 (s/cat ...) 和 (s/or) 以使序列规范。

输入可能看起来像 [0 1 2 3][\a \b \c \d],我尝试使用此规范。

(s/conform (s/cat :top (s/or :nums (s/+ #{0 1 2 3 4})
                             :letters (s/+ #{\a \b \c \d})
                  ... more stuff))
           [0 1 2 3])
=> :clojure.spec.alpha/invalid

如果只选择 :nums:letters 之一,则不使用 (s/or) 将可行。

(s/conform (s/cat :first-set (s/+ #{0 1 2 3 4}))
           [0 1 2 3])
=> {:first-set [0 1 2 3]}

初始示例如果在另一个 vec 中包装整个序列可行,但这不是我所想要的。

(s/conform (s/cat :first-set (s/or :nums (s/+ #{0 1 2 3 4})
                                   :letters (s/+ #{\a \b \c \d})))
           [[0 1 2 3]])
=> {:first-set [:nums [0 1 2 3]]}

(s/keys) 内使用 (or ...) 似乎也仅适用于正则表达式上下文。我猜这是因为 (or 无论如何总是匹配第一个规范,因为它不是假值。

(s/conform (s/cat :first-set (or (s/+ #{0 1 2 3 4})
                                 (s/+ #{\a \b \c \d})))
           [0 1 2 3])
=> {:first-set [0 1 2 3]}

(s/conform (s/cat :first-set (or (s/+ #{0 1 2 3 4})
                                 (s/+ #{\a \b \c \d})))
           [\a \b \c])
=> :clojure.spec.alpha/invalid

这是我想要的情况。

(s/conform (s/cat :first-set (s/something-here (s/+ #{0 1 2 3 4})
                                               (s/+ #{\a \b \c \d})))
           [0 1 2 3])
=> {:first-set [0 1 2 3]}

(s/conform (s/cat :first-set (s/something-here (s/+ #{0 1 2 3 4})
                                               (s/+ #{\a \b \c \d})))
           [\a \b \c])
=> {:first-set [\a \b \c]}

我在这里想知道该怎么做。

1 答案

+3

被选中
 
最佳答案

在正则表达式上下文中,应使用 s/alt 而不是 s/or

(s/conform (s/cat :top (s/alt :nums (s/+ #{0 1 2 3 4})
                              :letters (s/+ #{\a \b \c \d})))
           [0 1 2 3])
=> {:top [:nums
          [0 1 2 3]]}

因为 s/or 不是一个正则表达式操作符,所以它会匹配下一个项目而不是一个序列。

(s/conform (s/cat :top (s/or :nums (s/+ #{0 1 2 3 4})
                              :letters (s/+ #{\a \b \c \d})))
           [[0 1 2 3]]) ;; note that it's wrapped vector
=> {:top [:nums
          [0 1 2 3]]}
正则操作符的组合使得它们始终匹配单个集合,永远不会是嵌套集合。正则操作符包括 cat、alt、*、+、?、keys* 以及 &。
...