2016-04-01 7 views
4

に正規表現パターンに設定します。変換は、Clojureの

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

私の試み:

(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 

ベターアイデア?

+1

かっこはネストできますか? – rock321987

+0

固定しました、ありがとう! – leontalbot

+0

実行コードのideone.comリンクを教えていただけますか? – rock321987

答えて

3

文字列のあなたのセットがちょうど.それ以外のメタ文字を持っている可能性がある場合は、より一般的なアプローチはask the underlying java.util.regex.Pattern implementation to escape 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。 IDEoneはREPLではないことを覚えておいてください。たとえば、stdoutに値を設定するように指示する必要があります。 printlnが表示されます。

+1

'(apply str)'の代わりに、個々の引用符で囲まれたパターンを '|'で結合する必要があると思います。 '(clojure.string/join" | ")'それ以外の場合は正しく一致しません。 –

+0

ええ、私はそれについて忘れました。おそらくもっと良い解決策でしょう。 – Magos

+0

@Magosはい!もっと一般的なアプローチがいい考えです。ファイルには、しばしば名前に「 - 」が付いています... – leontalbot

2

あなたは最終的な解決策に近づいていました。ダブルバックスラッシュはエスケープされているため表示されます。あなたは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 
+0

右! 'seq'の説明に感謝します! – leontalbot

0

編集:OK、この1つは、実際の作業ではありません。おそらくそれが長命のコードであることを意図しているならば、それをもう少し分割したいと思うかもしれませんが、これは最小限の文字列で行うことができる最も簡単な方法です。

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

clojure.string /ここに脱出2つの引数を取ります。エスケープする文字列、および置換文字列にエスケープする文字のマッピングを。このマップのキーは、\.という文字列であり、再パターン関数の引数として使用する最後の文字列に.の前にバックスラッシュを1つ含める必要があるため、この値には2つのバックスラッシュが必要です。

関連する問題