当引号包含以:或​​#(正则表达式)开头的单词时,如何删除匹配的引号

时间:2019-06-16 11:37:25

标签: regex clojure

如果在字符串中检测到此模式:

双引号(#或:字符)其余单词,以双引号结束

我想从比赛中删除双引号

这是一个例子

"#sql/inline"

#sql/inline

":username"

:username

,但是"test"将保持不变 "test"

假设单词中没有\字符,这看起来就是我想要的

(clojure.string/replace example-string #"(\")(#|:)(.*?)(\")" "$2$3")

5 个答案:

答案 0 :(得分:6)

可以使用正则表达式

\"([#:][^\"]*)\"

替换为$1。请参见regex demoregex graph

enter image description here

关闭命令:

(clojure.string/replace example-string #"\"([#:][^\"]*)\"" "$1")

正则表达式详细信息

  • \"-双引号
  • ([#:][^\"]*)-捕获组1:
    • [#:]-一个#:字符
    • [^\"]*-除双引号之外的0个或多个字符
  • \"-双引号。

答案 1 :(得分:2)

或者如果我们在"中可能有多余的空格,则此表达式将删除那些空格:

"\s*([#:].+?)\s*"

,我们所需的数据在以下捕获组中:([#:].+?)

Demo

我们的代码可能如下:

(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中的外观。