clojure正则表达式命名组

时间:2014-09-17 13:41:41

标签: regex clojure

我在clojure中重新找到了一个问题。其实我正在做

(re-find #"-(?<foo>\d+)-(?<bar>\d+)-(?<toto>\d+)-\w{1,4}$" 
"http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu" )

我的结果很好:

["-9-31289-824-gt" "9" "31289" "824"]

但我希望哈希看起来像:

{:foo "9" :bar "31289" :toto "824"}

我已经知道java.util.regex.Matcher / group正在做类似的事情,但我还没有能够正确使用它。 谢谢你的帮助

2 个答案:

答案 0 :(得分:11)

针对(Java 1.6)构建的java正则表达式库Clojure不支持正则表达式的捕获组。

但是,您可以使用Clojure的zipmap函数将名称键和re-find捕获的组合并到一个地图中。未匹配的组将获得名称密钥的nil值。

(zipmap [:foo :bar :toto]
        (rest (re-find #"-(\d+)-(\d+)-(\d+)-\w{1,4}$" 
                        "http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu")))

=> {:foo "9" :bar "31289" :toto "824"}

答案 1 :(得分:9)

JDK在JDK 7之前不支持命名捕获组。

Here's announcement on oracle blog

引用:

  

这个方便的功能在Java RegEx中已经错过了多年,现在它终于在JDK7 b50中得到了它。

由于clojure支持JDK&gt; = 6,如果您正在寻找原生的东西(clojure在幕后使用java正则表达式模式和匹配器),那么您将失去运气。

您始终可以使用外部库,例如named-re。那个可以满足您的需求。

致电

(require 'named-re.core)
(re-find #"-(?<foo>\d+)-(?<bar>\d+)-(?<toto>\d+)-\w{1,4}$" 
     "http://www.bar.com/f-a-c-a-a3-spok-ser-2-phse-2-1-6-ti-105-cv-9-31289-824-gu" )

将返回

{:toto "824", :bar "31289", :foo "9", :0 "-9-31289-824-gu"}