0

如果有人可以帮助我,我对正则表达式很垃圾,非常感激。

我想这将是一个艰难的过程 - 所以我也向任何能解决它的人致敬!

假设我们的文件包含以下格式的 2 个 html 标签:

abc1234
<a href="http://google.com">Some Text</a> <P>
<a href="http://www.google.com" rel="nofollow">Some Text</a>
abc1234

我试图删除这些标签中的所有内容,除了 url(并留下其他文本),因此本文档中正则表达式的输出将是

abc1234
http://google.com <P>
http://www.google.com
abc1234

有哪位大师能解决这个问题吗?我更喜欢一个正则表达式来处理这两种情况,但两个单独的也可以。

提前致谢/

4

2 回答 2

2

ScottStevens,众所周知,尝试用正则表达式解析 html 是很困难的,事实上,关于这个问题有相当冗长的帖子。但是,如果这是唯一<a>采用的两种格式,那么这是解决问题的方法:

关于如何解决这个问题的第一个线索是两个标签都以 开头<a href=",并且你想把它去掉,为此,一个简单的 remove on'<a href="'就可以了,不需要正则表达式。

您的下一个线索是,有时,您的结束标签有时有">...</a>,有时有" rel=...</a>(从正则表达式的角度来看,rel= 和无关紧要)。现在注意" rel="...</a>它的某处包含一个">...</a>. 这意味着您可以" rel="...</a>分两步删除" rel="...,最多删除">,然后删除">...</a>。此外,为确保您仅删除 的一个标记<a...>...</a>,请添加附加约束,即在...">...</a>,不能有任何<a.

那和正则表达式备忘单可以帮助您入门。


也就是说,您应该真正使用 html 解析器。用于 PHP 的强大且成熟的 HTML 解析器

于 2012-07-23T17:27:18.793 回答
1

我是一名 Rubyist,所以我的示例将使用 Ruby。我建议使用两个正则表达式,只是为了保持直截了当:

url_reg = /<a href="(.*?)"/   # Matches first string within <a href=""> tag
tag_reg = /(<a href=.*?a>)/   # Matches entire <a href>...</a> tag

您需要将带有第一个正则表达式的 URL 拉出并临时存储,然后将标记的全部内容(与 tag_reg 匹配)替换为存储的 URL。

您也许可以将其结合起来,但这似乎不是一个好主意。您从根本上改变(通过删除)原始标签,并用其内部的东西替换它。如果您尽可能地将这两个步骤分开,那么出错的可能性就会降低。

Ruby 中的示例

def replace_tag(input)
  url_reg = /<a href="(.*?)"/    # Match URLS within an <a href> tag
  tag_reg = /(<a href=.*?a>)/     # Match an entire <a href></a> tag

  while (input =~ tag_reg) # While the input has matching <a href> tags
    url = input.scan(url_reg).flatten[0]  # Retrieve the first URL match
    input = input.sub(tag_reg, url)       # Replace first tag contents with URL
  end

  return input
end

File.open("test.html", "r") do |html_input|       # Open original HTML file
  File.open("output.html", "w") do |html_output|  # Open an output file
    while line = html_input.gets                  # Read each line
      output = replace_tag(line)                  # Perform necessary substitutions
      html_output.puts(output)                    # Write output lines to file
    end
  end
end

即使你不使用 Ruby,我希望这个例子是有意义的。我在您给定的输入文件上对此进行了测试,它产生了预期的输出。

于 2012-07-23T17:26:04.290 回答