Convert set to regex pattern in clojure

If i have this set

(def my-set #{"foo.clj" "bar.clj" "baz.clj"})

How can I rotate it to this template string:

"foo\.clj|bar\.clj|baz\.clj"

My attempt:

(defn set->pattern-str [coll] 
  (-> (clojure.string/join "|" coll) 
      (clojure.string/replace #"\." "\\\\.")))

(set->pattern-str my-set) 
=> "foo\\.clj|baz\\.clj|bar\\.clj" ;I get the double backslash

Best ideas?

+4
source share
3 answers

If your string set may contain other metacharacters, and not just .that, a more general approach is to request a basic implementation, java.util.regex.Patternavoid everything for us :

(import 'java.util.regex.Pattern)

(defn set->pattern-str [coll] 
  (->> coll
    (map #(Pattern/quote %))
    (clojure.string/join \|)
     re-pattern))

IDEone link here . Remember that IDEone is not a REPL, and you must tell it to add values ​​to stdout, for example. printlnbefore you can see them.

+3
source

. , . seq, :

(seq "foo\\.clj")
;;=> (\f \o \o \\ \. \c \l \j)

:

(def my-set #{"foo.clj" "bar.clj" "baz.clj"})

(def my-set-pattern
  (-> (clojure.string/join "|" my-set)
    (clojure.string/replace "." "\\.")
    (re-pattern)))

(re-matches my-set-pattern "foo.clj")
;;=> "foo.clj"

(re-matches my-set-pattern "bar.clj")
;;=> "bar.clj"

(re-matches my-set-pattern "baz.clj")
;;=> "baz.clj"

(re-matches my-set-pattern "foo-clj")
;;=> nil
+2

: , . , , , , , , .

(defn is-matching-file-name [target-string]
  (re-matches 
    (re-pattern (clojure.string/escape (String/join "|" my-set) {\. "\\."}))
    target-string))

clojure.string/escape : . - \., , , . , .

0

All Articles