【问题标题】:clojure regex named groupsclojure 正则表达式命名组
【发布时间】:2014-11-11 14:10:21
【问题描述】:

我在 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


    【解决方案1】:

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

    Here's announcement on oracle blog

    引用:

    这个方便的特性在 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"}
    

    【讨论】:

    • 我被这个例子弄糊涂了,直到我检查了项目源代码。使用它的一个重要警告是它修改了 Clojure 阅读器,并更改了评估 #"" 的规则,因此它不再返回 java.util.regex.Pattern 对象。
    • @noisesmith 是的。在返回 Pattern 对象的同时很难实现该功能,因为它不支持它。但老实说,这是我遇到的第一件事;)
    【解决方案2】:

    针对 (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"}
    

    【讨论】:

    • 考虑编写一个正则表达式从模式中提取命名组并使用 zipmap 匹配组以提供 Clojure 命名模式:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 2010-09-29
    • 2018-01-29
    • 2011-03-03
    • 2011-08-20
    相关资源
    最近更新 更多