Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure 用enlive提取连续的html片段_Clojure_Enlive - Fatal编程技术网

Clojure 用enlive提取连续的html片段

Clojure 用enlive提取连续的html片段,clojure,enlive,Clojure,Enlive,我需要删除具有以下格式的html: <div id='content'> <h3>Headline1</h3> <div>Text1</div> <div>Text2</div> <div>Text3</div> <h3>Headline2</h3> <div>Text4</div> &

我需要删除具有以下格式的html:

<div id='content'>
    <h3>Headline1</h3>
    <div>Text1</div>
    <div>Text2</div>
    <div>Text3</div>
    <h3>Headline2</h3>
    <div>Text4</div>
    <div>Text5</div>
    <h3>Headline3</h3>
    <div>Text6</div>
    <div>... and so on ...</div>
</div>

头条新闻1
文本1
文本2
文本3
头条新闻2
文本4
文本5
头条新闻3
文本6
... 等等
我需要将标题标记之间的内容作为单独的块。所以从一个标题到下一个标题。不幸的是,没有所需范围的容器标记

我尝试了片段选择器
{[:h3][:h3]}
,但不知何故,这只返回所有的h3标记,而不返回它们之间的标记:
({:tag:h3,:attrs nil,:content(“Headline1”)})({:tag:h3,:attrs nil,:content(“Headline2”)})({:tag:h3,:attrs nil,:content(“Headline3”)))

起作用的是
{[:h3(类型1的html/nth)]][[:h3(类型2的html/nth)]}
。这为我提供了第一个和第二个h3标记之间的所有html。但是,这并不能通过一个选择器提供所有所需的块

enlive能做到这一点吗?还是应该使用正则表达式


谢谢

选择div.content中的所有内容,然后根据标记对它们进行分区

这里有一个更一般的概念,即通过识别哪些事物是分隔符,哪些事物不是分隔符,将事物序列划分为多个部分:

(defn separate*
  "Produces a sequence of (parent child*)*, coll must start with a parent"
  [child? coll]
  (lazy-seq
   (when-let [s (seq coll)]
     (let [run (cons (first s)
                     (take-while child? (next s)))]
       (cons run (separate* child? (drop (count run) s)))))))
非常类似于按分区,但总是在父级上拆分:

(partition-by keyword? [:foo 1 2 3 :bar :baz 4 5])
;; => ((:foo) (1 2 3) (:bar :baz) (4 5))

(separate* (compliment keyword?) [:foo 1 2 3 :bar :baz 4 5])
;; => ((:foo 1 2 3) (:bar) (:baz 4 5))
如果要在没有前导标题时处理:

(defn separate
  [parent? coll]
  (when-let [s (seq coll)]
    (if (parent? (first coll))
      (separate* (complement parent?) coll)
      (let [child? (complement parent?)
            run (take-while child? s)]
        (cons (cons nil run)
              (separate* child? (drop (count run) s)))))))

(separate keyword? [1 2 :foo 3 4])
;; => ((nil 1 2) (:foo 3 4))
回到眼前的问题:

(def x [{:tag :h3 :content "1"}
        {:tag :div :content "A"}
        {:tag :div :content "B"}
        {:tag :h3 :content "2"}
        {:tag :div :content "C"}
        {:tag :div :content "D"}])

(def sections (separate #(= :h3 (:tag %)) x))
=> (({:content "1", :tag :h3}
     {:content "A", :tag :div
     {:content "B", :tag :div})
    ({:content "2", :tag :h3}
     {:content "C", :tag :div}
     {:content "D", :tag :div}))
如果我们不想保留h3标题的内容:

(map rest sections)
=> (({:content "A", :tag :div} {:content "B", :tag :div})
    ({:content "C", :tag :div} {:content "D", :tag :div}))

这个答案有用吗?:PS你不能用正则表达式来解析HTML:如果你尝试,你可能会唤醒那些古老的;-)不幸的是,这似乎没有帮助。当我用{[:h3][:h3]}选择时,我只会得到h3标记,而不会得到它们之间的节点。如果添加html代码段和选择器,我们可能会编写一个匹配的。如果你包括你现在得到的输出,你会得到额外的分数。嗨,我用一个片段和更详细的描述编辑了这篇文章。谢谢看起来棒极了。我一有时间就测试一下。。。谢谢