clojure 正则表达式命名组

问题描述 投票:0回答:3

我在 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 正在做类似的事情,但我无法正确使用它。 谢谢你的帮助

regex clojure
3个回答
13
投票

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

但是,您可以使用 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"}

11
投票

JDK 直到 JDK 7 才支持命名捕获组。

这是 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" )

会回来

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

0
投票

这长期以来一直是 Java 的一个限制。没有用于获取命名捕获组列表的 API。 请参阅这个问题

当使用不支持此功能的 Java 版本时,您所能做的就是使用外部库。

如果您不需要地图,您可以使用中描述的解决方案 Clojure 文档。对于您的情况,解决方案可能与此类似:

(let [matcher (re-matcher #"-(?<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")]
  (re-find matcher)
  (re-groups matcher)
  (.group matcher "foo"))

虽然这个解决方案并不完美(匹配器是一个可变的 Java 对象),但它有效。

正如我链接的另一个答案中所写,自 2023 年 3 月 21 日发布的 Java 20 以来,有一个 解决方案

(let [matcher (re-matcher #"-(?<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")]
  (re-find matcher)
  (re-groups matcher)
  (.namedGroups matcher))

这给了你你想要的。

我必须手动安装 JDK 20。JRE 不适合我。但是安装 JDK 20 之后,Clojure 接受了它并且它对我有用。无需配置。

对于 ClojureScript 显然这根本不起作用。

© www.soinside.com 2019 - 2024. All rights reserved.