加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

regex – 一个正则表达式,可以拆分具有相同嵌套括号的字符串

发布时间:2020-12-14 05:47:04 所属栏目:百科 来源:网络整理
导读:我知道正则表达式可用于编写检查括号的开始和结束符号对的检查器: 例如. a.[b.[c.d]].e屈服值a,[b.[c.d]]和e 如何编写正则表达式,可以找出相同符号的开始和结束括号 例如. a.| b.| c.d || .e将产生值a,| b.| c.d ||和e 更新 感谢所有的评论.我必须提出一些
我知道正则表达式可用于编写检查括号的开始和结束符号对的检查器:

例如. 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

我真的希望不使用解析器主要是因为我不知道怎么做,我不认为它证明了必要的复杂性.但如果正则表达式无法削减它,我可能不得不这样做.

解决方法

感谢@ m.buettner和@rafal,这是我在clojure中的代码:

有一个普通模式和管道模式.遵循m.buettner描述的内容:

助手:

(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))

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读