2014-01-28 42 views
1

在Clojure函数中耦合多个正则表达式的最佳方式是什么?我相信功能会从这样开始:Clojure中的多个正则表达式

(defn foo [x] 
(re-seq #"some means to combine multiple regex") 

但我不清楚这是否会起作用,或者这样的功能的效率。为了提供可能的正则表达式耦合的例子,可以考虑一个搜索域名和IP的函数。对于域名我会使用一个正则表达式这样:

(re-seq #"\b([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}\b" x) 

和IP:

(re-seq #"\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b") 

回答

6

Regexs已经允许与|操作交替。

user=> (re-seq #"\d+" "123 foo 345 bar") 
("123" "345") 
user=> (re-seq #"[a-zA-Z]+" "123 foo 345 bar") 
("foo" "bar") 
user=> (re-seq #"\d+|[a-zA-Z]+" "123 foo 345 bar") 
("123" "foo" "345" "bar") 

你可以,如果正则表达式模式期望通过插入|操作编程工会。

(defn union-re-patterns [& patterns] 
    (re-pattern (apply str (interpose "|" (map #(str "(" % ")") patterns))))) 

user=> (union-re-patterns #"\d+" #"[a-zA-Z]+") 
#"(\d+)|([a-zA-Z]+)" 
user=> (map first (re-seq (union-re-patterns #"\d+" #"[a-zA-Z]+") "123 foo 345 bar")) 
("123" "foo" "345" "bar") 
+2

这工作的大部分时间,但如果一个模式的采用了编号捕获组?例如'(。)\ 1 {5}',用于连续六次匹配任何字符?你添加的额外的parens搞乱了组编号;你需要使用'(?:'而不是'(')。 – amalloy

4

根据您的使用情况,frak可能是您正在搜索的; FRAK转换字符串的集合到正则表达式匹配这些字符串:

(frak/pattern ["foo" "bar" "baz" "quux"]) 
;; => #"(?:ba[rz]|foo|quux)"