Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在clojure中,如何编写应用多个字符串替换的函数?_Clojure - Fatal编程技术网

在clojure中,如何编写应用多个字符串替换的函数?

在clojure中,如何编写应用多个字符串替换的函数?,clojure,Clojure,我想编写一个函数replace multive,它接收一个字符串和一组替换,并应用所有替换(替换可以看到以前替换的结果) 我考虑了以下界面: (replace-several "abc" #"a" "c" #"b" "l" #"c" "j"); should return "jlj" 两个问题: 它是clojure中最惯用的界面吗 如何实现这个功能 备注:要进行单个替换,在中有可用的replace,

我想编写一个函数
replace multive
,它接收一个字符串和一组替换,并应用所有替换(替换可以看到以前替换的结果)

我考虑了以下界面:

(replace-several "abc" #"a" "c" 
                       #"b" "l"
                       #"c" "j"); should return "jlj" 
两个问题:

  • 它是clojure中最惯用的界面吗
  • 如何实现这个功能

  • 备注:要进行单个替换,在中有可用的
    replace
    ,因此您有
    replace
    reduce
    分区
    。从这些构建块中,您可以构建您的
    替换几个

    第一次猜测

    (defn replace-several [string & mappings]
      (loop [grouped-mappings (partition 2 mappings) string string]
        (if (empty? grouped-mappings)
          string
          (let [[re rep] (first grouped-mappings)]
            (recur (rest grouped-mappings) (clojure.string/replace string re rep))))))
    ; => (replace-several "abc" #"a" "c" #"b" "l" #"c" "j")
      "jlj"
    

    使用
    replace
    reduce
    partition
    实现@kotarak的建议:

    (defn replace-several [content & replacements]
          (let [replacement-list (partition 2 replacements)]
            (reduce #(apply string/replace %1 %2) content replacement-list)))
    ; => (replace-several "abc" #"a" "c" #"b" "l" #"c" "j")
      "jlj"
    

    这里是另一个快照,但是它的输出结果不同,这一个使用了正则表达式引擎功能,因此可能更快,而且界面也不同,因为它将键映射到替换字符串。我提供这个,以防它可能对有类似问题的人有用

    (defn replace-map
      "given an input string and a hash-map, returns a new string with all
      keys in map found in input replaced with the value of the key"
      [s m]
      (clojure.string/replace s
                  (re-pattern (apply str (interpose "|" (map #(java.util.regex.Pattern/quote %) (keys m)))))
              m))
    
    因此,用法如下所示:

     (replace-map "abc" {"a" "c" "b" "l" "c" "j"})
    

    =>“clj”

    您可以使用reduce和replace:

    (defn replace-several
      [str & replacements]
      (reduce (fn [s [a b]]
                (clojure.string/replace s a b))
              str
              (partition 2 replacements)))
    
    (replace-several "abc"
                     #"a" "c"
                     #"b" "l"
                     #"c" "j")
    

    我来晚了,但无论如何,我认为最惯用的方法是使用线程和多个替换:

    (require '[clojure.string :refer [replace])
    
    (-> "abc"
        (replace #"a" "c")
        (replace #"b" "l")
        (replace #"c" "j"))
    
    ;=> "jlj"
    

    这一点的含义非常清楚,尽管避免多次键入“replace”很好。

    我个人不会为此创建单独的函数,因为它只是现有Clojure函数的组合:

    (reduce kv clojure.string/replace“Hello”{#“[A-Z]”“J”、“o”“y”}
    ;=>“果冻”

    当然,如果您想要varargs和接口,那么:

  • 是的,它看起来相当地道
  • 我将这样实施它:
  • (defn替换许多[string&{:as rplcmnts}]
    (减少kv clojure.string/replace string rplcmnts))


    Docs

    刚刚注意到你可以将
    val
    参数传递给reduce函数,如果不是因为你的评论,我永远不会意识到!看到我对kotarak的回复中的评论,我不知道你可以将
    val
    参数传递给
    reduce
    来累积结果,这与我的答案几乎相同。唯一的区别是e是在reduce中,我用了
    应用
    而不是解构。你的意思是
    (替换几个“abc”…
    ?@Josh我不理解你的问题我是说我认为
    “abd”
    中的“d”是一个打字错误,对吗?当然应该是
    “abc”
    ,或者您描述的
    替换多个
    功能会很奇怪。谢谢@Josh。您完全正确。事实上,我在回答中答对了:)谢谢这一块金子。我完全错过了
    escape
    。非常好。我会把它添加到箭袋中。谢谢你的这段代码,正是我想要的。我还不太理解你的代码,但我尝试过:
    (替换地图“这是一个检查它是否按预期工作的测试”{“这是”“htis si”“检查是否”“hceck fi”“按预期运行”“任意”})
    而且它工作得很好!如果您想知道它是如何工作的,我正在创建一个由映射键组成的正则表达式。
    clojure.string/replace
    将使用该正则表达式并将匹配项传递给
    m
    ,该函数起到函数的作用。因为
    m
    已经是要替换的映射,它将返回正确的替换.
    (str/escape "abc" {\a "c" \b "l" \c "j"})
    
    ; => "clj"