clojure正则表达式命名组

Eli*_*ias 9 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" )
Run Code Online (Sandbox Code Playgroud)

我的结果很好:

["-9-31289-824-gt" "9" "31289" "824"]
Run Code Online (Sandbox Code Playgroud)

但是我希望哈希看起来像:

{:foo "9" :bar "31289" :toto "824"}
Run Code Online (Sandbox Code Playgroud)

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

Nie*_*lsK 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"}
Run Code Online (Sandbox Code Playgroud)


sou*_*eck 9

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

这是oracle博客上的公告

引用:

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

由于clojure支持JDK> = 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" )
Run Code Online (Sandbox Code Playgroud)

将返回

{:toto "824", :bar "31289", :foo "9", :0 "-9-31289-824-gu"}
Run Code Online (Sandbox Code Playgroud)

  • 在我检查项目源之前,我对此示例感到困惑.关于使用它的一个重要警告是它修改了Clojure读取器,并更改了评估#""的规则,因此它不再返回`java.util.regex.Pattern`对象. (4认同)