Clojure中如何用re-seq/re-pattern精确匹配函数名?
解决Clojure函数名精确匹配统计问题
问题根源
当前的f函数用普通字符串作为正则匹配时,会匹配所有包含目标子串的内容,比如"str"会匹配"str-path"里的前缀部分,导致统计结果超出预期。我们需要的是匹配独立的函数名符号,而非任意子串。
修正后的精确匹配函数
修改正则表达式,使用单词边界确保只匹配独立的符号,同时用re-escape处理函数名中的正则特殊字符(比如+、*这类Clojure函数名):
(defn f "精确匹配给定符号并统计其在文本中的出现次数" [symbol text] (count (re-seq (re-pattern (str "\\b" (re-escape symbol) "\\b")) text)))
测试验证
(def function-text "str-path str") (f "str" function-text) ; => 1 符合预期
扩展到批量文件统计
针对你扫描本地仓库clj/cljs/cljc文件、统计核心函数调用次数的需求,这里提供一个完整的实现思路:
(require '[clojure.java.io :as io]) (defn f "精确匹配给定符号并统计其在文本中的出现次数" [symbol text] (count (re-seq (re-pattern (str "\\b" (re-escape symbol) "\\b")) text))) (defn count-core-functions-in-dir [dir-path core-functions] ;; 筛选目标后缀的文件 (let [target-files (filter #(#{".clj" ".cljs" ".cljc"} (io/file-extension %)) (file-seq (io/file dir-path)))] ;; 遍历所有文件,汇总每个函数的调用次数 (reduce (fn [result file] (let [content (slurp file)] (merge-with + result (into {} (map #(vector % (f % content)) core-functions))))) {} target-files))) ;; 调用示例:统计str、map、filter在指定目录的调用次数 (count-core-functions-in-dir "/path/to/your/repo" ["str" "map" "filter"])
进阶优化提示
如果需要更精准的统计(避免误匹配注释、字符串字面量中的内容),建议使用Clojure的语法解析库(如clojure.tools.reader)将代码解析为抽象语法树(AST),再遍历AST统计函数调用,这种方式能完全规避字符串匹配的局限性。
内容的提问来源于stack exchange,提问作者Barış Can Ateş
相关产品推荐
相关产品推荐

