在以下情况下,我试图仅捕获第二种情况,即文本与useEffect(() => {
let something = somethingelse;
setSearchList(searchList => [...searchList, search]);
}, [search]);
相匹配。目前,它捕获了这两种情况。
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
。有人告诉我不要用正则表达式解析html,但是现在我被卡住了。
答案 0 :(得分:2)
您实际上已经很接近了,因为您已经在使用适当的解析器(html.Parse
中的golang.org/x/net/html
)。
这里的技巧是将页面的各个元素方便地绑定在一起,因此,您可以根据需要将现有的crawler
代码与更高版本的过滤功能一起使用。 (您可以将过滤条件直接组合到搜寻器中。)
每个n *html.ElementNode
之前都有一些东西,除非它是块中的初始元素(文档或第一个子节点的第一个),并且 something 位于n.PrevSibling
中。如果其类型为html.TextNode
,则具有以下形式的序列:
some text<a ...>thing</a>
,您可以检查上一个节点中的“一些文本”:
func wanted(re *regexp.Regexp, n *html.Node) bool {
if n.PrevSibling == nil || n.PrevSibling.Type != html.TextNode {
return false
}
return re.MatchString(n.PrevSibling.Data)
}
这不是完美的,因为您可能拥有例如:
text <font></font> broken <font></font>up<a href="lastlink">last link</a>
,当您可能应该将文本放到up
中并将其传递给匹配器时,代码将尝试与字符串text broken up
进行匹配。查看更完整的示例here。