(defn cutting
[str result]
(if (empty? str)
result
(recur (rest str) (conj result str))))
(defn cutting-string
[string]
(map #(apply str %) (cutting string [])))
(defn star-end-pattern
"匹配結(jié)尾是星號(hào)的情況"
[pattern pattern-point]
(if (and (< pattern-point (count pattern))
(= \* (nth pattern pattern-point)))
(recur pattern (inc pattern-point))
(>= pattern-point (count pattern))))
(defn next-star-point
"獲得最右方的星號(hào)位置"
[pattern pattern-point]
(cond (>= (inc pattern-point) (count pattern))
pattern-point,
(= \* (nth pattern (inc pattern-point)))
(recur pattern (inc pattern-point)),
(not= \* (nth pattern (inc pattern-point)))
pattern-point))
(defn match
"匹配帶通配符的字符串"
[pattern string pattern-point string-point]
(let [str-length (count string),
pattern-length (count pattern)]
(cond
(>= string-point str-length) ;;字符串到了末尾(結(jié)束)的情況禽额,可以繼續(xù)被 * 匹配
(star-end-pattern pattern pattern-point),
(>= pattern-point pattern-length) false, ;;如果匹配串結(jié)束但是字符串沒(méi)有結(jié)束
(= \* (nth pattern pattern-point)) ;; 通配符匹配
(let [p-behind-star (subs pattern (inc (next-star-point pattern pattern-point))),
strs (cutting-string (subs string string-point str-length)),
result (map #(match p-behind-star % 0 0)
(cutting-string (subs string string-point str-length)))]
(not (empty? (filter true? result))))
(not= (nth pattern pattern-point) (nth string string-point)) false, ;;非通配符匹配失敗
:else (recur pattern string (inc pattern-point) (inc string-point)))))
(defn match-filename
[fmt file]
(match fmt file 0 0))
簡(jiǎn)單測(cè)試
(match-filename "*a*b" "aababa")
=> false
(match-filename "*a*b" "aaab")
=> true
(match-filename "*a*b" "aabab")
=> true
(match-filename "*a*b*" "aabab")
=> true
(match-filename "*a*b*" "ab")
=> true