我在clojure中有一个re-find的问题。实际上我在做
(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正在做类似的事情,但我不能正确地使用它。谢谢你的帮助
3条答案
按热度按时间wxclj1h51#
Clojure构建的java regex库(Java 1.6)不支持regex命名的捕获组。
但是,您可以使用Clojure的
zipmap
函数将合并名称键和re-find
捕获的组组合到一个map中。不匹配的组将获得名称键的nil
值。mwg9r5ms2#
JDK直到JDK 7才支持命名捕获组。
Here's announcement on oracle blog
报价:
这个方便的特性在Java RegEx中已经被忽略了很多年,现在它终于在JDK 7 b50中得到了体现。
由于clojure支持JDK >= 6,如果你正在寻找一些原生的东西(clojure在幕后使用java regex Patterns和Matchers),那你就不走运了。
您可以始终使用外部库,如named-re。这一个给你正是你需要的。
调用
将返回
jhdbpxl93#
这在Java中是一个长期的限制。没有用于获取命名捕获组列表的API。看看这个question。
当使用不支持此功能的Java版本时,您所能做的就是使用外部库。
如果不需要Map,可以使用Clojure文档中描述的解决方案。在您的情况下,解决方案可以类似于这样:
尽管这个解决方案并不完美(匹配器是一个可变的Java对象),但它是有效的。
正如我链接的另一个答案中所写的那样,自2023年3月21日发布的Java 20以来,有一个解决方案。
这是你想要的
我不得不手动安装JDK 20。JRE不适合我。但是在安装了JDK 20之后,Clojure接受了它,它对我很有效。不需要配置。
使用ClojureScript显然这根本不起作用。