我知道正则表达式可以用来编写检查器来检查括号的开始和结束符号对:
。a.[b.[c.d]].e
产率值a
、[b.[c.d]]
、e
我如何写一个正则表达式,可以找出开始和结束括号是相同的符号
。a.|b.|c.d||.e
将产生a
、|b.|c.d||
和e
感谢所有的评论。我必须给这个问题提供一些背景。我想模仿javascript语法
a.hello is a["hello"] or a.hello
a.|hello| is a[hello]
a.|b.c.|d.e||.f.|g| is a[b.c[d.e]].f[g]
那么我要做的就是把这些符号分解成:
[`a`, `|b.c.|d.e||`, `f`, `|g|`]
,如果它们是双引号
我在这里有一个没有管道的语法实现:
https://github.com/zcaudate/purnam我真的不希望主要使用解析器,因为我不知道如何使用,而且我不认为它证明了必要的复杂性。但是如果regex不能截断它,我可能不得不。
感谢@m。Buettner和@rafal,这是我在clojure中的代码:
有一个normal-mode
和pipe-mode
。按照m.b ettner的描述:
助手:
(defn conj-if-str [arr s]
(if (empty? s) arr
(conj arr s)))
(defmacro case-let [[var bound] & body]
`(let [~var ~bound]
(case ~var ~@body)))
管模式:
(declare split-dotted) ;; normal mode declaration
(defn split-dotted-pipe ;; pipe mode
([output current ss] (split-dotted-pipe output current ss 0))
([output current ss level]
(case-let
[ch (first ss)]
nil (throw (Exception. "Cannot have an unpaired pipe"))
| (case level
0 (trampoline split-dotted
(conj output (str current "|"))
"" (next ss))
(recur output (str current "|") (next ss) (dec level)))
. (case-let
[nch (second ss)]
nil (throw (Exception. "Incomplete dotted symbol"))
| (recur output (str current ".|") (nnext ss) (inc level))
(recur output (str current "." nch) (nnext ss) level))
(recur output (str current ch) (next ss) level))))
正常模式:(defn split-dotted
([ss]
(split-dotted [] "" ss))
([output current ss]
(case-let
[ch (first ss)]
nil (conj-if-str output current)
. (case-let
[nch (second ss)]
nil (throw (Exception. "Cannot have . at the end of a dotted symbol"))
| (trampoline split-dotted-pipe
(conj-if-str output current) "|" (nnext ss))
(recur (conj-if-str output current) (str nch) (nnext ss)))
| (throw (Exception. "Cannot have | during split mode"))
(recur output (str current ch) (next ss)))))
测试:
(fact "split-dotted"
(js/split-dotted "a") => ["a"]
(js/split-dotted "a.b") => ["a" "b"]
(js/split-dotted "a.b.c") => ["a" "b" "c"]
(js/split-dotted "a.||") => ["a" "||"]
(js/split-dotted "a.|b|.c") => ["a" "|b|" "c"]
(js/split-dotted "a.|b|.|c|") => ["a" "|b|" "|c|"]
(js/split-dotted "a.|b.c|.|d|") => ["a" "|b.c|" "|d|"]
(js/split-dotted "a.|b.|c||.|d|") => ["a" "|b.|c||" "|d|"]
(js/split-dotted "a.|b.|c||.|d|") => ["a" "|b.|c||" "|d|"]
(js/split-dotted "a.|b.|c.d.|e|||.|d|") => ["a" "|b.|c.d.|e|||" "|d|"])
(fact "split-dotted exceptions"
(js/split-dotted "|a|") => (throws Exception)
(js/split-dotted "a.") => (throws Exception)
(js/split-dotted "a.|||") => (throws Exception)
(js/split-dotted "a.|b.||") => (throws Exception))