【问题标题】:How to create a "replace-second" function in Clojure?如何在 Clojure 中创建“替换秒”功能?
【发布时间】:2022-01-08 00:17:54
【问题描述】:

(clojure.string/replace-first "a x x c d" #"x" "b" )) ; Replace first

如果我想替换上面字符串中的第二个 x 怎么办?

【问题讨论】:

    标签: clojure


    【解决方案1】:

    Matcher 实例让我们iterate over the matches

    (defn replace-nth [input pattern n new-value]
      (let [m (re-matcher pattern input)]
        (loop [counter n]
          (if (.find m)
            (if (= counter 0)
              (str (subs input 0 (.start m))
                   new-value
                   (subs input (.end m)))
              (recur (dec counter)))
            input))))
    
    (replace-nth "a x x c d" #"x" 1 "Mjao!")
    ;; => "a x Mjao! c d"
    

    【讨论】:

    • 如果找不到pattern,则返回nil。比较(s/replace-first "a x x c d" #"p" "Mjao!")(replace-nth "a x x c d" #"p" 1 "Mjao!")
    • @MartinPůda 说得好!我已经更新了代码。
    【解决方案2】:

    嗯,也许你可以妥协?

    (-> "a x x c d"  
      (clojure.string/replace-first #"x" "_")
      (clojure.string/replace-first #"x" "b" )
      (clojure.string/replace-first #"_" "x"))
    

    只要确保_ 不能在字符串中。

    :)

    【讨论】:

      【解决方案3】:

      例如,它可能是:

      (let [n     #{1}
                s     "a x x x x c d"
                re    #"x"
                m     (re-find re s)
                xs    (s/split s re)
                vs    (conj (vec (take (dec (count xs)) (repeat m))) nil)
                replacement ".."]
              (apply str (interleave xs (map-indexed (fn [index v] (if (n index) replacement v)) vs))))
      

      【讨论】:

        【解决方案4】:

        好的,这里还有一个(模块化的):

        首先,要替换的范围的惰性序列:

        (defn ranges [re s]
          (let [m (re-matcher re s)]
            (for [_ (range) :while (re-find m)]
              [(.start m) (.end m)])))
        
        user> (ranges #"x" "a x x b x")
        ;;=> ([2 3] [4 5] [8 9])
        

        然后是范围替换函数:

        (defn replace-range [[a b] repl s]
          (str (subs s 0 a) repl (subs s b)))
        
        user> (replace-range [1 3] "REPLACED" "a b c d e f")
        
        ;;=> "aREPLACED c d e f"
        

        然后你做任何你需要的:

        (let [s "a x x b x"]
          (map #(replace-range % "ZEE" s)
               (ranges #"x" s)))
        
        ;;=> ("a ZEE x b x" "a x ZEE b x" "a x x b ZEE")
        

        (let [s "a x x b x"]
          (-> (ranges #"x" s)
              second
              (replace-range "REPLACED" s)))
        
        ;;=> "a x REPLACED b x"
        

        【讨论】:

          猜你喜欢
          • 2019-06-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-04
          相关资源
          最近更新 更多