我必须找到一种方法来提取<div id="links">
和</table>
标记之间的所有链接。
如果有多个链接,则应在网址之间添加“\ n”字符:“$ URL1 \ n $ URL2”。
<div id="links">
<table>
<td><a href="URL">url</a></td>
<td><a href="URL">url</a></td>
</table>
<table>
..
</table>
</div>
<div>
代码与第一个</table>
代码之间的代码。
除了sed之外还有其他方法吗?
谢谢。
答案 0 :(得分:2)
每天在SO上发布:您无法使用正则表达式处理HTML。 Can you provide some examples of why it is hard to parse XML and HTML with a regex?
对于像sed一样有限的工具,它的基本正则表达式会增加一倍。
如果您输入的类型非常有限,以至于每个链接的格式完全相同,则可能是这样,在这种情况下您必须发布该格式的示例。但对于一般的HTML页面,它无法完成。
ETA给出了你的例子:在最简单的层面上,因为每个URL已经在它自己的行上,你可以选择看起来正确的那些并丢弃你不想要的那些:
#!/bin/sed -f
s/^<td><a href="\(.*\)">.*<\/a><\/td>$/\1/p
d
但是请注意,这仍然会将URL保留为HTML编码形式。如果生成此文件的脚本正确地对其URL进行HTML编码,则必须将lt / gt / quot / amp实体引用的任何实例替换回其简单字符形式'&lt;&gt;“&amp;'。在实践中,您可能遇到的唯一一个是&amp; / amp,这在URL中非常常见。
但是!这不是可能发生的所有HTML编码。也许还有其他HTML实体引用,比如eacute(现在我们有IRI就有效),或者数字字符引用(十进制和十六进制)。对于包括Unicode在内的字符,有两百多种可能的编码形式...在sed中单独替换每一种形式将是乏味的大规模练习。
虽然如果你知道生成器脚本永远不会输出任何内容,你可能会侥幸逃脱它,但HTML解析器仍然是最好的。 (或者,如果您知道它是格式良好的XHTML,您可以使用更简单的XML解析器,它通常内置于现代语言的标准库中。)
答案 1 :(得分:0)
如果你有权访问python我会推荐BeautifulSoup。一个很好的python库,用于操作HTML。以下代码收集来自给定资源的链接,该资源是http://www.foo.com等网页的全名,并将其存储在文件中。希望这会有所帮助。
import sys, os
from urllib import urlopen
from BeautifulSoup import BeautifulSoup
fileLinksName = "links.dat"
if __name__ == "__main__":
try:
# get all links so far
fileLinks = open(fileLinksName)
links = fileLinks.read().split('\n')
fileLinks.close()
htmlFileSoup = BeautifulSoup(urlopen(sys.argv[1]).read())
anchorList = htmlFileSoup.findAll('a')
for htmlAnchor in anchorList:
print htmlAnchor
if 'href' in htmlAnchor:
links.append(htmlAnchor)
for link in links:
print link
except:
print sys.exc_info()
exit()
答案 2 :(得分:0)
如果不是试图查看您只是寻找网址的标记,那么这可能是可能的。
如果这些是页面中唯一的URL,您可以编写一个模式来查找引号之间的URL,如:
"[a-z]+://[^"]+"
答案 3 :(得分:0)
您是否可以访问AWK? AWK和sed的组合可能会做你想要的,只要:
您无法使用正则表达式处理HTML,这是错误的。确实,在一般情况下,您无法使用正则表达式处理HTML(或XML),因为它们允许任意嵌套,并且正则表达式不能很好地进行递归 - 或者根本不进行递归。但是如果你的HTML相对“平淡”,你肯定会对正则表达式做很多事情。
我无法告诉你到底要做什么,因为我已经忘记了我在大学里学到的一点点AWK和sed,但这让我觉得可行:
<div id="links">
<table>
<td>...</td>
并从中获取一个链接(这是正则表达式部分)。$links
</table>
$links
将每个链接与\n
分开。同样,这只是简单案例的伪代码。但它可能会奏效。
我提到AWK是因为,即使您无法访问Perl,也会安装sed和AWK。
最后,对于纯粹的sed解决方案,您还可以查看this sed recipe并根据您的需求进行调整。