用字符串替换 UUID
Replace the UUIDs with Strings
我想使用 Clojure 将 UUID 替换为字符串,但不确定如何为其创建函数。
这是原始值:/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964
并希望看到如下内容
/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id
但动态足以处理以下示例,
案例一
输入:
/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car
预期结果:
/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car
案例二
输入:
/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car
预期结果:
/user-1/user-1-id/user-2/user-2-id/car
案例三
输入:
/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire
预期结果:
/user-1/user-1-id/user-2/user-2-id/car/tire
这是一种方法,基于 my favorite template project
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.string :as str]
[tupelo.uuid :as uuid]
))
(defn replace-uuids
[input-str]
; use `let-spy-pretty` below to see step-by-step results
(let [segments (str/split input-str #"/")
pairs (partition-all 2 segments)
; looks like:
; [["" "v1"]
; ["user-1" "4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964"]
; ["user-2" "7badb866-44fc-43c7-9cf4-aa3c2f8cc964"]
; ["user-3" "27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"]]
version-pair (first pairs)
user-pairs (rest pairs)
user-pairs-mod (for [pair user-pairs]
(let [user-part (first pair)
uuid-part (second pair)]
(if (uuid/uuid-str? uuid-part)
[user-part (str user-part "-id")]
pair)))
all-pairs-mod (flatten [version-pair user-pairs-mod])
result (str/join (interpose "/" all-pairs-mod))]
result))
(dotest
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"))
)
对于更通用的解决方案,您可能只想使用正则表达式,这是 uuid-str?
内部所做的。
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
[tupelo.string :as str]
))
(def full-regex
#"(?x) # expanded form
/ # a slash
([a-zA-Z0-9-_]+) # repeated identifier char in a capture group
/ # a slash
\p{XDigit}{8} # 8 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{12} # 12 hex digits
")
(s/defn replace-uuids :- s/Str
[s :- s/Str]
(str/replace s full-regex
(fn [arg]
(let ; use `let-spy` to see intermediate steps
[x1 (second arg)
result (str "/" x1 "/" x1 "-id")]
result))))
结果
(dotest
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"))
)
Clojure Spec 对这类事情很方便。这是一种方法:
(require '[clojure.spec.alpha :as spec]
'[clojure.string :as cljstr])
(spec/def ::fixkey-format
(spec/cat :root #{""}
:version #{"v1"}
:pref1 #{"user-1"}
:user-1 string?
:pref2 #{"user-2"}
:user-2 string?
:pref3 #{"user-3"}
:user-3 string?))
(defn replace-values [input new-values]
(cljstr/join
"/"
(spec/unform
::fixkey-format
(merge (spec/conform ::fixkey-format (cljstr/split input #"/")) new-values))))
(replace-values "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"
{:user-1 "x"
:user-2 "y"
:user-3 "z"})
;; => "/v1/user-1/x/user-2/y/user-3/z"
或者只是字面上做简单的字符串替换
(clojure.string/replace
"/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"
#"/(user-\d+)/[0-9a-f\-]+(?=/|$)"
"//-id")
;;=> "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(defn normalize-path [path]
(clojure.string/replace path #"/(user-\d+)/[0-9a-f\-]+(?=/|$)" "//-id"))
(map normalize-path
["/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"])
;;=> ("/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire")
您还可以像这样更新正则表达式以仅匹配有效的 uid:
(defn normalize-path [path]
(clojure.string/replace
path
#"/(user-\d+)/[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}(?=/|$)"
"//-id"))
(map normalize-path
["/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"
"/v2/user-101/asd-asd-asd/user-2/xxx"
"/v3/user-404/aa44ddss-3333-4444-aaaa/user-505/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964"])
;; ("/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire"
;; "/v2/user-101/asd-asd-asd/user-2/xxx"
;; "/v3/user-404/aa44ddss-3333-4444-aaaa/user-505/user-505-id")
我想使用 Clojure 将 UUID 替换为字符串,但不确定如何为其创建函数。
这是原始值:/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964
并希望看到如下内容
/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id
但动态足以处理以下示例,
案例一
输入:
/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car
预期结果:
/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car
案例二
输入:
/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car
预期结果:
/user-1/user-1-id/user-2/user-2-id/car
案例三
输入:
/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire
预期结果:
/user-1/user-1-id/user-2/user-2-id/car/tire
这是一种方法,基于 my favorite template project
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[tupelo.string :as str]
[tupelo.uuid :as uuid]
))
(defn replace-uuids
[input-str]
; use `let-spy-pretty` below to see step-by-step results
(let [segments (str/split input-str #"/")
pairs (partition-all 2 segments)
; looks like:
; [["" "v1"]
; ["user-1" "4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964"]
; ["user-2" "7badb866-44fc-43c7-9cf4-aa3c2f8cc964"]
; ["user-3" "27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"]]
version-pair (first pairs)
user-pairs (rest pairs)
user-pairs-mod (for [pair user-pairs]
(let [user-part (first pair)
uuid-part (second pair)]
(if (uuid/uuid-str? uuid-part)
[user-part (str user-part "-id")]
pair)))
all-pairs-mod (flatten [version-pair user-pairs-mod])
result (str/join (interpose "/" all-pairs-mod))]
result))
(dotest
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"))
)
对于更通用的解决方案,您可能只想使用正则表达式,这是 uuid-str?
内部所做的。
(ns tst.demo.core
(:use tupelo.core tupelo.test)
(:require
[schema.core :as s]
[tupelo.string :as str]
))
(def full-regex
#"(?x) # expanded form
/ # a slash
([a-zA-Z0-9-_]+) # repeated identifier char in a capture group
/ # a slash
\p{XDigit}{8} # 8 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{4} # 4 hex digits
- # hyphen
\p{XDigit}{12} # 12 hex digits
")
(s/defn replace-uuids :- s/Str
[s :- s/Str]
(str/replace s full-regex
(fn [arg]
(let ; use `let-spy` to see intermediate steps
[x1 (second arg)
result (str "/" x1 "/" x1 "-id")]
result))))
结果
(dotest
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"))
(is= "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire"
(replace-uuids "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"))
)
Clojure Spec 对这类事情很方便。这是一种方法:
(require '[clojure.spec.alpha :as spec]
'[clojure.string :as cljstr])
(spec/def ::fixkey-format
(spec/cat :root #{""}
:version #{"v1"}
:pref1 #{"user-1"}
:user-1 string?
:pref2 #{"user-2"}
:user-2 string?
:pref3 #{"user-3"}
:user-3 string?))
(defn replace-values [input new-values]
(cljstr/join
"/"
(spec/unform
::fixkey-format
(merge (spec/conform ::fixkey-format (cljstr/split input #"/")) new-values))))
(replace-values "/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"
{:user-1 "x"
:user-2 "y"
:user-3 "z"})
;; => "/v1/user-1/x/user-2/y/user-3/z"
或者只是字面上做简单的字符串替换
(clojure.string/replace
"/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964"
#"/(user-\d+)/[0-9a-f\-]+(?=/|$)"
"//-id")
;;=> "/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id"
(defn normalize-path [path]
(clojure.string/replace path #"/(user-\d+)/[0-9a-f\-]+(?=/|$)" "//-id"))
(map normalize-path
["/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"])
;;=> ("/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire")
您还可以像这样更新正则表达式以仅匹配有效的 uid:
(defn normalize-path [path]
(clojure.string/replace
path
#"/(user-\d+)/[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}(?=/|$)"
"//-id"))
(map normalize-path
["/v1/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car"
"/user-1/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964/user-2/7badb866-44fc-43c7-9cf4-aa3c2f8cc964/user-3/27ebd241-44fc-43c7-9cf4-aa3c2f8cc964/car/tire"
"/v2/user-101/asd-asd-asd/user-2/xxx"
"/v3/user-404/aa44ddss-3333-4444-aaaa/user-505/4bcbe877-44fc-43c7-9cf4-aa3c2f8cc964"])
;; ("/v1/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car"
;; "/user-1/user-1-id/user-2/user-2-id/user-3/user-3-id/car/tire"
;; "/v2/user-101/asd-asd-asd/user-2/xxx"
;; "/v3/user-404/aa44ddss-3333-4444-aaaa/user-505/user-505-id")