如何匹配 `<a>` 标记之前的文本然后返回 `<a>` 节点?

我有以下内容,我试图仅捕获文本匹配的第二种情况But I want this one here。目前,它涵盖了这两种情况。


package main


import (

    "bytes"

    "fmt"

    "io"

    "strings"


    "golang.org/x/net/html"

)


func getTag(doc *html.Node, tag string) []*html.Node {

    var nodes []*html.Node

    var crawler func(*html.Node)

    crawler = func(node *html.Node) {

        if node.Type == html.ElementNode && node.Data == tag {

            nodes = append(nodes, node)

            return

        }

        for child := node.FirstChild; child != nil; child = child.NextSibling {

            crawler(child)

        }

    }

    crawler(doc)

    return nodes

}


func main() {

    doc, _ := html.Parse(strings.NewReader(testHTML))

    nodes := getTag(doc, "a")


    var buf bytes.Buffer

    w := io.Writer(&buf)

    for i, node := range nodes {

        html.Render(w, node)

        if i < (len(nodes) - 1) {

            w.Write([]byte("\n"))

        }

    }


    fmt.Println(buf.String())

}


var testHTML = `<html><body>

I do not want this link here <a href="blah">link text</a>

But I want this one here <a href="blah blah">more link text</a>

</body></html>`

这输出:


<a href="blah">link text</a>

<a href="blah blah">more link text</a>


我想匹配<a>标签之前的特定文本,如果匹配,则返回<a>节点。例如,传入But I want this one here并返回<a href="blah blah">more link text</a>. 有人告诉我不要用正则表达式解析 html,但现在我被卡住了。


森林海
浏览 144回答 1
1回答

子衿沉夜

您实际上非常接近,因为您已经在使用正确的解析器(html.Parsefrom golang.org/x/net/html)。这里的诀窍是页面的各种元素很方便地绑定在一起,所以crawler如果你愿意,你可以使用你现有的代码和以后的过滤功能。(您可以改为将过滤直接组合到爬虫中。)每个n *html.ElementNode前面都有一些东西,除非它是块中的初始元素(文档的第一个元素或第一个子节点),并且某个东西在n.PrevSibling. 如果它的类型是html.TextNode你有一个形式的序列:some text<a ...>thing</a>您可以检查上一个节点中的“一些文本”:func wanted(re *regexp.Regexp, n *html.Node) bool {&nbsp; &nbsp; if n.PrevSibling == nil || n.PrevSibling.Type != html.TextNode {&nbsp; &nbsp; &nbsp; &nbsp; return false&nbsp; &nbsp; }&nbsp; &nbsp; return re.MatchString(n.PrevSibling.Data)}这并不完美,因为您可以拥有,例如:text <font></font> broken <font></font>up<a href="lastlink">last link</a>并且代码将尝试匹配 string up,当您可能应该将文本放在一起text broken up并将其传递给匹配器时。在此处查看更完整的示例。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go