在文件中搜索关键字并在Clojure中找到它的值

时间:2016-11-01 00:11:04

标签: clojure

我有一个文件“test.txt”,内容如下:

TAG A    : HELLO 
DATE START   : Tue Oct 25 09:51:49 EDT 2015 
GIT BRANCH   : master 
GIT COMMIT   : fecb1b53ec8fffffffffffffffffffff09523c42 

我必须从这个文件中找到“GIT BRANCH”的值,该文件应该是“master”。

我实现这一目标的逻辑是逐行读取此文件,匹配关键字“GIT BRANCH”并找出它的值。 我能够逐行读取文件并匹配关键字,但我不知道如何获得它的价值。

我是Clojure的新手,非常感谢任何帮助实现这一目标。

感谢。

4 个答案:

答案 0 :(得分:2)

一般情况下,我不会编写专门针对此用例的代码。当你缩小一点时,你可以解决一个更通用的版本,并可能在将来再次使用该功能。

这是我的版本,您可以使用简单的(get your-map "GIT BRANCH")

获得最终结果
(def ff "
TAG A    : HELLO
DATE START   : Tue Oct 25 09:51:49 EDT 2015
GIT BRANCH   : master
GIT COMMIT   : fecb1b53ec8fffffffffffffffffffff09523c42 ")

(defn kv-parser
  [sep]
  (fn [s]
    (let [[k v] (mapv str/trim (str/split s sep))]
      (when (not-empty k)
        [k v]))))

(with-open [rdr (BufferedReader. (StringReader. ff))]
  (into {}
        (map (kv-parser #":"))
        (line-seq rdr)))

;; For reading a file you'd do:
(with-open [rdr (io/reader "./your-file")]
  (into {}
        (map (kv-parser #":"))
        (line-seq rdr)))

地图也很懒,所以你不需要使用整个文件,以防你在某个时候在一个巨大的文件上使用它。

答案 1 :(得分:1)

我认为最好的方法是保持简单并映射文件数据。然后,您可以从地图中获取您感兴趣的密钥的值,在本例中为"GIT BRANCH"。通过首先映射文件数据,如果您需要获取"TAG A"之类的其他信息,那将很容易。

(require [clojure.java.io :as io])
(def kv-re #"\s*(.*\S)\s*:\s+(.*\S)")  ;; regex to capture key and value
(def git-info
     (with-open [rdr (io/reader "test.txt")]
       (into {}
             (map #(vec (rest (re-find kv-re %)))  ;; map list of [k v]
                  (line-seq rdr)))))

现在您可以从git-info中提取值,如下所示:

(get git-info "GIT BRANCH")  ;; -> "master"
(get git-info "TAG A")       ;; -> "HELLO"
(get git-info "TAG B")       ;; -> nil
(get git-info "TAG B" "foo") ;; -> "foo"

答案 2 :(得分:0)

显然这很黑,但这就是你需要的......

(defn solution [input]
    (let [index-of-key (clojure.string/index-of input "GIT BRANCH")
          next-newline (clojure.string/index-of (subs input index-of-key) "\n")]
  (clojure.string/trim (subs input (+ (count "GIT BRANCH   : ") index-of-key) 
                    (+ index-of-key next-newline))))) 

index-of-keyGIT BRANCH在字符串上开始的地方。 next-newlineGIT BRANCH之后的第一个换行符,因此它是我们感兴趣的行的结尾(我们不再看)。 知道了这两个值后,我们找到了输入的子字符串,它从GIT BRANCH :的末尾开始,到此后的第一个换行符结束。

示例:

user> (def input "TAG A    : HELLO 
       DATE START   : Tue Oct 25 09:51:49 EDT 2015 
       GIT BRANCH   : master 
       GIT COMMIT   : fecb1b53ec8fffffffffffffffffffff09523c42")
#'user/input
user> (solution input)
"master"


user> (def input "TAG A    : HELLO 
       DATE START   : Tue Oct 25 09:51:49 EDT 2015 
       GIT BRANCH   : my-other-branch
       GIT COMMIT   : fecb1b53ec8fffffffffffffffffffff09523c42")
#'user/input
user> (solution input)
"my-other-branch"

答案 3 :(得分:0)

我认为你需要使用正则表达式来处理这个问题。

(def ff "TAG A    : HELLO 
         DATE START   : Tue Oct 25 09:51:49 EDT 2015 
         GIT BRANCH   : master 
         GIT COMMIT   : fecb1b53ec8fffffffffffffffffffff09523c42")



(second (re-find  #"GIT BRANCH\s*:\s*(\w+)\n" ff))