首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将字符串中的字符替换为Clojure中映射中的一组字符

将字符串中的字符替换为Clojure中映射中的一组字符
EN

Stack Overflow用户
提问于 2022-05-17 01:12:55
回答 3查看 256关注 0票数 3

我有一个函数,它接受一个字符串s和一个字符映射charmap。如果字符串s中的任何字符在charmap中,请用映射的值替换该字符。

Note,映射中的键必须是字符串,而不是字符。

例如:

代码语言:javascript
复制
(replace-characters "Hi!" {"!" "Exclamation Mark"}) ;; => "HiExclamation Mark"

这是我目前使用的代码:

代码语言:javascript
复制
(defn- replace-characters
  "Replaces any characters in a string that are mapped in the given charmap"
  [s charmap]
  (let [character-set (set s)
        characters (filter #(contains? charmap (str %)) character-set)]
    (string/replace s (re-pattern (string/join "|" characters)) charmap)))

然而,我得到了一个NullPointerException,我真的很困惑为什么。

代码语言:javascript
复制
java.lang.NullPointerException: Cannot invoke "String.indexOf(int)" because "s" is null

我想用纯Clojure来解决这个问题,最好是用Java,等等。

更新:所以上面的代码可以在repl中工作。这很好。但由于某种原因,下列原因导致了错误:

代码语言:javascript
复制
(-> s
     (string/replace #"[:/?#\[\]@!$&'()*+,;=]" "")
     (replace-characters charmap)) ;; Where charmap is a large map of key value characters.
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-05-17 05:36:24

这是导致错误的表达式:

代码语言:javascript
复制
(str/replace "Hi" #"" {"!" "Exclamation Mark"})

("!"被regex替换为""character-set有值#{\H \i}characters(),所以用re-pattern创建的模式是#""。)

空regex匹配字母之间的每个空格:

代码语言:javascript
复制
(str/replace "Hi" #"" " ")

=> " H i "

因此,replace正在寻找散列映射{"!" "Exclamation Mark"}中的替代品,但是没有发现任何东西--没有键""

代码语言:javascript
复制
(str/replace "Hi" #"" {"!" "Exclamation Mark"})
=> error

(str/replace "Hi" #"" {"" " "})
=> " H i "

一种可能的解决方案是简化replace-characters的定义(此解决方案仅适用于非空charmap):

代码语言:javascript
复制
(defn replace-characters [s charmap]
  (str/replace s (re-pattern (str/join "|" (keys charmap)))
               charmap))

测试:

代码语言:javascript
复制
(replace-characters "Hi!" {"!" "Exclamation Mark"})

=> "HiExclamation Mark"

(-> "Hi!"
    (str/replace #"[:/?#\[\]@!$&'()*+,;=]" "")
    (replace-characters {"!" "Exclamation Mark"}))

=> "Hi"
票数 1
EN

Stack Overflow用户

发布于 2022-05-17 07:52:23

我只想用这样简单的方法:

代码语言:javascript
复制
(apply str (replace {"!" "[exclamation mark]"
                         "?" "[question mark]"}
                       (map str "is it possible? sure!")))

;;=> "is it possible[question mark] sure[exclamation mark]"

或者用这种方式换能器:

代码语言:javascript
复制
(apply str (eduction (map str) (replace {"!" "[exclamation mark]"
                                                "?" "[question mark]"})
                        "is it possible? sure!"))

或者像这样:

代码语言:javascript
复制
(defn replace-characters [s rep]
  (apply str (map #(rep (str %) %) s)))

user> (replace-characters "is it possible? sure!" {"!" "[exclamation mark]"
                                                            "?" "[question mark]"})

;;=> "is it possible[question mark] sure[exclamation mark]"
票数 0
EN

Stack Overflow用户

发布于 2022-05-17 09:44:03

string/escape完全可以做您想做的事情:

代码语言:javascript
复制
(string/escape "Hi!" {\! "Exclamation Mark"})
;; => "HiExclamation Mark"

该函数使用从一个字符到另一个字符的映射替换字符。

如果要替换regexes或string,可以将reduce-kvstring/replace结合使用。

代码语言:javascript
复制
(def replacements
  (array-map
   "!" "Exclamation Mark"
   #"[:/?#\[\]@!$&'()*+,;=]" ""
   #_more_replacements))

(defn replace [s replacements]
  (reduce-kv string/replace s replacements))

因此,在替换的键和值上循环(当replacementsarray-map时,按顺序排列),并使用string/replace将它们应用到字符串s上。

代码语言:javascript
复制
(replace "Hi!" replacements)
;; => "HiExclamation Mark"

如果array-map中元素的顺序颠倒,则替换!与"" (自!会成功的:

代码语言:javascript
复制
(replace "Hi!" (into (array-map) (reverse replacements)))
;; => "Hi"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72267167

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档