在字符串中替换字符,用clojure中地图中的一组字符

发布于 2025-01-29 07:48:21 字数 1065 浏览 2 评论 0原文

我有一个功能,该函数添加了字符串s和一个字符的地图charmap。如果字符串s中的任何字符都在charmap的内部,请用地图的值替换字符。

注意,地图中的键必须是字符串,而不是字符串。

例如:

(replace-characters "Hi!" {"!" "Exclamation Mark"}) ;; => "HiExclamation Mark"

这是我当前正在使用的代码:

(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,我对原因感到非常困惑。

java.lang.NullPointerException: Cannot invoke "String.indexOf(int)" because "s" is null

我想在纯clojure中解决这个问题,最好是Java等

。这很好。但是由于某种原因,以下原因是导致错误:

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

I have a function that takes in a string s and a map of characters charmap. If any characters in the string s are inside of charmap, replace the character with the value of the map.

Note, the keys in the map must be a string, rather than a char.

For example:

(replace-characters "Hi!" {"!" "Exclamation Mark"}) ;; => "HiExclamation Mark"

This is the code I am currently using:

(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)))

However, I am getting a NullPointerException and I am seriously confused on why.

java.lang.NullPointerException: Cannot invoke "String.indexOf(int)" because "s" is null

I would like to solve this in pure Clojure preferably, not Java, etc.

Update: So the code above works in the repl. Which is nice. But for some reason the following is causing the error:

(-> s
     (string/replace #"[:/?#\[\]@!
amp;'()*+,;=]" "")
     (replace-characters charmap)) ;; Where charmap is a large map of key value characters.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

∞觅青森が 2025-02-05 07:48:21

这是导致错误的表达式:(

(str/replace "Hi" #"" {"!" "Exclamation Mark"})

“!”被正则替换为“”, targine> targine-set 具有值## {\ h \ i}字符 is (),因此使用re repattern IS ###创建的模式“。)

空的正则态度与字母之间的每个空间匹配:

(str/replace "Hi" #"" " ")

=> " H i "

so,替换正在寻找在哈希映射{“!”中替换。 “感叹号”},但找不到任何东西 - 没有键“”

(str/replace "Hi" #"" {"!" "Exclamation Mark"})
=> error

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

一种可能的解决方案可以简化repent> replace-characters的定义。 (此解决方案仅适用于非Expry-Code> CharMap ):

(defn replace-characters [s charmap]
  (str/replace s (re-pattern (str/join "|" (keys charmap)))
               charmap))

测试:

(replace-characters "Hi!" {"!" "Exclamation Mark"})

=> "HiExclamation Mark"

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

=> "Hi"

This is the expression that causes error:

(str/replace "Hi" #"" {"!" "Exclamation Mark"})

("!" was replaced with regex to "", character-set has value #{\H \i} and characters is (), so pattern created with re-pattern is #"".)

Empty regex matches every space between letters:

(str/replace "Hi" #"" " ")

=> " H i "

So, replace is looking for replacement in hash-map {"!" "Exclamation Mark"}, but doesn't find anything- there is no key "":

(str/replace "Hi" #"" {"!" "Exclamation Mark"})
=> error

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

One possible solution can be to simplify definition of replace-characters (this solution will work only for non-empty charmap):

(defn replace-characters [s charmap]
  (str/replace s (re-pattern (str/join "|" (keys charmap)))
               charmap))

Tests:

(replace-characters "Hi!" {"!" "Exclamation Mark"})

=> "HiExclamation Mark"

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

=> "Hi"
你的他你的她 2025-02-05 07:48:21

我只会和这样简单的事情:

(apply str (replace {"!" "[exclamation mark]"
                         "?" "[question mark]"}
                       (map str "is it possible? sure!")))

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

或这样使用传感器:

(apply str (eduction (map str) (replace {"!" "[exclamation mark]"
                                                "?" "[question mark]"})
                        "is it possible? sure!"))

或者可能是这样:

(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]"

i would just go with something as simple as this:

(apply str (replace {"!" "[exclamation mark]"
                         "?" "[question mark]"}
                       (map str "is it possible? sure!")))

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

or this way with transducers:

(apply str (eduction (map str) (replace {"!" "[exclamation mark]"
                                                "?" "[question mark]"})
                        "is it possible? sure!"))

or maybe like this:

(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]"
跨年 2025-02-05 07:48:21

string> string/code确切地做您想要的事情:

(string/escape "Hi!" {\! "Exclamation Mark"})
;; => "HiExclamation Mark"

该功能替代字符使用从角色到更换的地图。

如果要替换REGEXES或字符串,则可以使用 redain-kv < < < < < /a>与 string/替换

(def replacements
  (array-map
   "!" "Exclamation Mark"
   #"[:/?#\[\]@!
amp;'()*+,;=]" ""
   #_more_replacements))

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

(按顺序,当替换 /code> )在替换的密钥和值上,并使用String/replact在字符串s上应用它们。

(replace "Hi!" replacements)
;; => "HiExclamation Mark"

如果array-map中的元素的顺序颠倒了!使用“”(因为!在以下是正则>)将成功:

(replace "Hi!" (into (array-map) (reverse replacements)))
;; => "Hi"

string/escape does exactly what you want:

(string/escape "Hi!" {\! "Exclamation Mark"})
;; => "HiExclamation Mark"

that function replaces characters using a map from character to replacement.

If you want to replace regexes or string you can use reduce-kv in combination with string/replace:

(def replacements
  (array-map
   "!" "Exclamation Mark"
   #"[:/?#\[\]@!
amp;'()*+,;=]" ""
   #_more_replacements))

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

So you loop (in order, when replacements is an array-map) over the key and values of the replacements and apply them on the string s using string/replace.

(replace "Hi!" replacements)
;; => "HiExclamation Mark"

if the order of the elements in the array-map is reversed the substitution of the ! with "" (since ! is in the regex) would succeed:

(replace "Hi!" (into (array-map) (reverse replacements)))
;; => "Hi"
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文