我有一个包含html的文本字符串,我需要提取每个url(最有可能是img或标签)来创建字符串对象的通用列表。我只想要来自html标签内的网址,而不是文本中的网址。有没有一种简单的方法可以做到这一点,还是我必须诉诸正则表达式?
如果我不得不诉诸正则表达式,你还介意帮我解决这个问题吗? :)
更新 要回答Seph,输入将是标准的html。
<p>This is some html text. my favourite website is <a href="http://www.google.com">google</a> and my favourite help site is <a href="http://www.stackoverflow.com">stackoverflow</a> and i check my email at <a href="http://www.gmail.com">gmail</a>. the url to my site is http://www.mysite.com. <img src="http://www.someserver.com/someimage.jpg" alt=""/></p>
我想要
最终结果应该是任何html标签中的所有网址,忽略那些是“纯文本”
UPPERDATE 虽然他删除了答案,但我要感谢Jerry Bullard引起我的注意 Regex Buddy(http://www.regexbuddy)。我想提出你的答案,但它已经消失了。把它带回来你就得票了!
答案 0 :(得分:1)
这样的事情应该会有所帮助:
private List<string> GetUrlStrings(string text)
{
List<string> listURL = new List<string>();
Regex regex = new Regex("href\\s*=\\s*(?:(?:\\\"(?<url>[^\\\"]*)\\\")|(?<url>[^\\s]* ))");
MatchCollection mathColl = regex.Matches(text);
foreach (Match match in mathColl)
{
foreach (Group group in match.Groups)
{
if (!group.Value.StartsWith("href")) // workaround regex issue
{
listURL.Add(group.Value);
}
}
}
return listURL;
}
答案 1 :(得分:1)
以下是使用LINQ to XML和regex的两种方法。虽然有些人对使用正则表达式解析HTML感到不满,但这种特殊情况并没有嵌套元素,所以这是一个合理的解决方案。 LINQ to XML仅在HTML格式正确时才有效。否则,请查看HTML Agility Pack。
样本Elements()
的 编辑与LINQ to XML一起使用。但是,如果您有许多嵌套的HTML标记,那么您可能希望使用Descendants()
来覆盖所有需要的标记。
string input = @"<p>This is some html text. my favourite website is <a href=""http://www.google.com"">google</a> and my favourite help site is <a href=""http://www.stackoverflow.com"">stackoverflow</a> and i check my email at <a href=""http://www.gmail.com"">gmail</a>. the url to my site is http://www.mysite.com. <img src=""http://www.someserver.com/someimage.jpg"" alt=""""/></p>";
var xml = XElement.Parse(input);
var result = xml.Elements()
.Where(e => e.Name == "img" || e.Name == "a")
.Select(e => e.Name == "img" ?
e.Attribute("src").Value : e.Attribute("href").Value);
foreach (string item in result)
{
Console.WriteLine(item);
}
string pattern = @"<(?:a|img).+?(?:href|src)=""(?<Url>.+?)"".*?>";
foreach (Match m in Regex.Matches(input, pattern))
{
Console.WriteLine(m.Groups["Url"].Value);
}
编辑#2:为了回应您关于RegexBuddy的更新,我想指出我使用的工具。 Expresso是一个很好的免费工具(仅限电子邮件注册,但它是免费的)。作者还写了The 30 Minute Regex Tutorial,您可以使用它来跟随它,并包含在Expresso的帮助文件中。
答案 2 :(得分:-1)
此代码可能有所帮助:)取自http://www.vogella.de/articles/JavaRegularExpressions/article.html。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class LinkGetter {
private Pattern htmltag;
private Pattern link;
private final String root;
public LinkGetter(String root) {
this.root = root;
htmltag = Pattern.compile("<a\\b[^>]*href=\"[^>]*>(.*?)</a>");
link = Pattern.compile("href=\"[^>]*\">");
}
public List<String> getLinks(String url) {
List<String> links = new ArrayList<String>();
try {
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(new URL(url).openStream()));
String s;
StringBuilder builder = new StringBuilder();
while ((s = bufferedReader.readLine()) != null) {
builder.append(s);
}
Matcher tagmatch = htmltag.matcher(builder.toString());
while (tagmatch.find()) {
Matcher matcher = link.matcher(tagmatch.group());
matcher.find();
String link = matcher.group().replaceFirst("href=\"", "")
.replaceFirst("\">", "");
if (valid(link)) {
links.add(makeAbsolute(url, link));
}
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return links;
}
private boolean valid(String s) {
if (s.matches("javascript:.*|mailto:.*")) {
return false;
}
return true;
}
private String makeAbsolute(String url, String link) {
if (link.matches("http://.*")) {
return link;
}
if (link.matches("/.*") && url.matches(".*$[^/]")) {
return url + "/" + link;
}
if (link.matches("[^/].*") && url.matches(".*[^/]")) {
return url + "/" + link;
}
if (link.matches("/.*") && url.matches(".*[/]")) {
return url + link;
}
if (link.matches("/.*") && url.matches(".*[^/]")) {
return url + link;
}
throw new RuntimeException("Cannot make the link absolute. Url: " + url
+ " Link " + link);
}
}