pis*_*hio 5 regex string clojure
如果我试试这个
(import java.util.regex.Pattern)
(Pattern/compile ")!@#$%^&*()")
Run Code Online (Sandbox Code Playgroud)
或这个
(def p #")!@#$%^&*()")
Run Code Online (Sandbox Code Playgroud)
我有Clojure抱怨说有一个无与伦比的/未闭合的).为什么在这个简单的字符串中评估括号?怎么逃避他们?谢谢
编辑:虽然转义在特定于clojure的语法(#"")中工作,但它不能用Pattern/compile我需要的语法,因为我必须从字符串动态编译正则表达式模式.
我试过了re-pattern,但由于某种原因我无法正常逃脱:
(re-pattern "\)!@#$%^&*\(\)")
java.lang.Exception: Unsupported escape character: \)
java.lang.Exception: Unable to resolve symbol: ! in this context (NO_SOURCE_FILE:0)
java.lang.Exception: No dispatch macro for: $
java.lang.Exception: Unable to resolve symbol: % in this context (NO_SOURCE_FILE:0)
java.lang.IllegalArgumentException: Metadata can only be applied to IMetas
Run Code Online (Sandbox Code Playgroud)
编辑2这个小功能可能会有所帮助:
(defn escape-all [x]
(str "\\" (reduce #(str %1 "\\" %2) x)))
Run Code Online (Sandbox Code Playgroud)
Omr*_*ein 10
我通过双重逃避一切来实现它.哦,双重逃避的乐趣.
=> (re-pattern "\\)\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)")
=> #"\)\!\@\#\$\%\^\&\*\(\)"
=> (re-find (re-pattern "\\)\\!\\@\\#\\$\\%\\^\\&\\*\\(\\)")
")!@#$%^&*()")
=> ")!@#$%^&*()"
Run Code Online (Sandbox Code Playgroud)
我建议编写一个辅助函数str-to-pattern(或任何你想要的函数),它接受一个字符串,双重转义所需的一切,然后调用re-pattern它.
编辑:使字符串模式化功能
有很多方法可以做到这一点,下面只是一个例子.我首先将正则表达式转义为字符串替换."smap"不是实际类型,但从功能上来说,它是我们用来将"旧值"与"新值"交换的地图,其中"旧值"是smap键的成员,以及"新值"是相应的smap的成员.在我们的例子中,这个smap看起来像{\( "\\(", \) "\\)" ...}.
(def regex-char-esc-smap
(let [esc-chars "()*&^%$#!"]
(zipmap esc-chars
(map #(str "\\" %) esc-chars))))
Run Code Online (Sandbox Code Playgroud)
接下来是实际功能.我使用上面的smap替换传递给它的字符串中的项目,然后将其转换回字符串并从中生成正则表达式模式.我认为->>宏使代码更具可读性,但这只是个人偏好.
(defn str-to-pattern
[string]
(->> string
(replace regex-char-esc-smap)
(reduce str)
re-pattern))
Run Code Online (Sandbox Code Playgroud)