如果在字符串中检测到此模式:
双引号(#或:字符)其余单词,以双引号结束
我想从比赛中删除双引号
这是一个例子
"#sql/inline"
到
#sql/inline
或
":username"
到
:username
,但是"test"
将保持不变
"test"
假设单词中没有\字符,这看起来就是我想要的
(clojure.string/replace example-string #"(\")(#|:)(.*?)(\")" "$2$3")
答案 0 :(得分:6)
可以使用正则表达式
\"([#:][^\"]*)\"
替换为$1
。请参见regex demo和regex graph:
关闭命令:
(clojure.string/replace example-string #"\"([#:][^\"]*)\"" "$1")
正则表达式详细信息
\"
-双引号([#:][^\"]*)
-捕获组1:
[#:]
-一个#
或:
字符[^\"]*
-除双引号之外的0个或多个字符\"
-双引号。答案 1 :(得分:2)
或者如果我们在"
中可能有多余的空格,则此表达式将删除那些空格:
"\s*([#:].+?)\s*"
,我们所需的数据在以下捕获组中:([#:].+?)
。
我们的代码可能如下:
(clojure.string/replace example-string #"\"\s*([#:].+?)\s*\"" "$1")
答案 2 :(得分:1)
假设单词中没有\
个字符,看起来像这样,
(clojure.string/replace example-string #"(\")(#|:)(.*?)(\")" "$2$3")
答案 3 :(得分:1)
已经有几个很好的正则表达式答案,但是在Clojure中您不需要 正则表达式:
(defn remove-quote-wrapper [s]
(if (and (or (cs/starts-with? s "\"#")
(cs/starts-with? s "\":"))
(cs/ends-with? s "\""))
(subs s 1 (dec (count s)))
s))
如果您关心性能,则此方法比使用正则表达式的clojure.string/replace
快4倍。
答案 4 :(得分:0)
提出的解决方案的一个问题是它们不能正确识别文本中引用的部分。
让我们将引号为#
或:
开头的部分称为“特殊”,其余部分称为“非特殊”。
例如,在文本"a"#b"c"
中,"#b"
被识别为特殊部分,并且产生了"a#bc"
,而"a"
和"c"
应该是识别为非特殊部分,文本应保持不变。
另一个问题是引号内的"
和\
的转义无法处理。
考虑到这些问题的一种可能的解决方案如下:
(defn remove-quotes [s]
(clojure.string/replace s
#"\"([#:]?)(?:([^\"\\]+)|\\([\"\\]))*\""
#(if (empty? (second %)) (first %) (apply str (rest %)))))
编辑:
在阅读了Taylor Wood的回答(仅处理有限的情况)之后,我决定添加一个无正则表达式的解决方案(该解决方案不处理转义):
(defn remove-quotes [s]
(loop [processed "" remaining s]
(if-let [i (clojure.string/index-of remaining \u0022)]
(let [j (clojure.string/index-of remaining \u0022 (inc i))]
(recur
(str processed
(subs remaining 0 i)
(apply subs remaining
(if (#{\# \:} (get remaining (inc i)))
[(inc i) j]
[i (inc j)])))
(subs remaining (inc j))))
(str processed remaining))))
\u0022
只是\"
。后者弄乱了代码在Stack Overflow中的外观。