用于列表项的通用匹配的正则表达式样式匹配库

时间:2014-04-16 20:48:46

标签: clojure

我以前见过这样的图书馆,但后来却忘记了它的名字。

您可以指定与列表中的元素匹配的模式,类似于:

(def oddsandevens (pattern (n-of odd? :*) (n-of even? 2) :$))

(pattern-match oddsandevens [1 1 2 2]) => true
(pattern-match oddsandevens [1 1 1 2 2]) => true

(pattern-match oddsandevens [1 1 2 2 2]) => false
(pattern-match oddsandevens [1 1 2]) => false

如果我完全想象这一点,有人可以阐明一个人如何写下这些东西吗?

2 个答案:

答案 0 :(得分:2)

评论太长了:

如果你想要自己成长,你可能会发现Brzozowski关于Derivatives of Regular Expressions的文章很有用。它描述了一种将正则表达式转换为识别它的状态机的有效技术。另一个来源是John Conway的书Regular Algebra and Finite Machines

我感觉@leontalbot找到的Christopher Grand's GitHub project已经完成了这项工作,但由于我没有适当的开发环境,我无法做到调查。虽然他的终端类是字符串,但他定义了一个正则表达式的协议,他的联合和序列(和星?)符合。

环顾其他语言。

  • Scala执行Clojure所做的事情:包装Java正则表达式。
  • Boost民众有一些​​C ++的东西。目前尚不清楚是否 要求终端是字符。

抱歉,我无能为力。


添加了备注:

答案 1 :(得分:1)

更一般地说,您要求一种表达方式来解析序列。 Clojure当然有许多解析库,但是其中许多complect解析了(在优化性能方面可能有很好的理由),因此只能用于字符串。你可能不得不在toolbox之外寻找一个解析器,它允许lexing作为一个单独的关注点。

例如,The Parsatron(仅重262位)

(require '[the.parsatron ; sampling of available combinators 
            :refer [run token attempt many times choice always never >> eof]])

(defn matches? [parser input] 
  (run 
    (choice 
      (attempt (>> parser (eof) (always true))) 
      (always false))
    input))

现在定义你的模式

(def odds-and-evens (>> (many (token odd?)) (times 2 (token even?))))

并测试

(matches? odds-and-evens [1 1 2 2])   ;=> true
(matches? odds-and-evens [1 1 1 2 2]) ;=> true
(matches? odds-and-evens [1 1 2 2 2]) ;=> false
(matches? odds-and-evens [1 1 2])     ;=> false

从这里你可以添加糖来根据需要指定你的模式。