我有以下HTML代码:
<td class="actual">106.2% </td>
我通过两个阶段获得了这个数字:
Regex.Matches(html, "<td class=\"actual\">\\s*(.*?)\\s*</td>", RegexOptions.Singleline);
Regex.Match(m.Groups[1].Value, @"-?\d+.\d+").Value
上面的代码行给了我想要的东西,106.2
问题在于,有时HTML可能会有所不同,例如:
<td class="actual"><span class="revised worse" title="Revised From 107.2%">106.4%</span></td>
在最后一种情况下,我只能得到107.2,我想获得106.4 是否有一些正则表达技巧可以说,我想要句子中的第二个数字而不是第一个?
答案 0 :(得分:2)
如果您拥有来自不同提供商的HTML代码,或者您当前拥有多个使用不同HTML格式样式的CMS,那么依赖正则表达式是不安全的。
我建议使用基于HtmlAgilityPack的解决方案:
public string getCleanHtml(string html)
{
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
return HtmlAgilityPack.HtmlEntity.DeEntitize(doc.DocumentNode.InnerText);
}
然后:
var txt = "<td class=\"actual\">106.2% </td>";
var clean = getCleanHtml(txt);
txt = "<td class=\"actual\"><span class=\"revised worse\" title=\"Revised From 107.2%\">106.4%</span></td>";
clean = getCleanHtml(txt);
结果:和
您不必担心内部格式化标记以及任何XML / HTML实体引用。
如果您的文本是干净HTML字符串的子字符串,则可以使用Regex或任何其他字符串操作方法。
<强>更新强>:
您似乎需要<td>
标记中的节点值。这是一个方便的方法:
private List<string> GetTextFromHtmlTag(string html, string tag)
{
var result = new List<string>();
HtmlAgilityPack.HtmlDocument hap;
Uri uriResult;
if (Uri.TryCreate(html, UriKind.Absolute, out uriResult) && uriResult.Scheme == Uri.UriSchemeHttp)
{ // html is a URL
var doc = new HtmlAgilityPack.HtmlWeb();
hap = doc.Load(uriResult.AbsoluteUri);
}
else
{ // html is a string
hap = new HtmlAgilityPack.HtmlDocument();
hap.LoadHtml(html);
}
var nodes = hap.DocumentNode.ChildNodes.Where(p => p.Name.ToLower() == tag.ToLower() && p.GetAttributeValue("class", string.Empty) == "previous"); // SelectNodes("//"+tag);
if (nodes != null)
foreach (var node in nodes)
result.Add(HtmlAgilityPack.HtmlEntity.DeEntitize(node.InnerText));
return result;
}
您可以这样称呼它:
var html = "<td class=\"previous\"><span class=\"revised worse\" title=\"Revised From 1.3\">0.9</span></td>\n<td class=\"previous\"><span class=\"revised worse\" title=\"Revised From 107.2%\">106.4%</span></td>";
var res = GetTextFromHtmlTag(html, "td");
如果您只需要获取特定标签,
如果您的文字内部有数字,而您只需要数字,则可以使用正则表达式:
var rx = new Regex(@"[+-]?\d*\.?\d+"); // Matches "-1.23", "+5", ".677"
请参阅demo
答案 1 :(得分:1)
string html = @"<td class=""actual""><span class=""revised worse"" title=""Revised From 107.2%"">106.4%</span></td>
<td class=""actual"">106.2% </td>";
string patten = @"<td\s+class=""actual"">.*(?<=>)(.+?)(?=</).*?</td>";
foreach (Match match in Regex.Matches(html, patten))
{
Console.WriteLine(match.Groups[1].Value);
}
我已根据您的意愿更改了正则表达式,输出为
106.4%
106.2%
答案 2 :(得分:1)
尝试XML方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication34
{
class Program
{
static void Main(string[] args)
{
string input = "<td class=\"actual\"><span class=\"revised worse\" title=\"Revised From 107.2%\">106.4%</span></td>";
XElement element = XElement.Parse(input);
string value = element.Descendants("span").Select(x => (string)x).FirstOrDefault();
}
}
}
答案 3 :(得分:1)
我想分享我为我的问题找到的解决方案。
所以,我可以使用以下HTML标签:
<td class="previous"><span class="revised worse" title="Revised From 1.3">0.9</span></td>
<td class="previous"><span class="revised worse" title="Revised From 107.2%">106.4%</span></td>
或更简单:
<td class="previous">51.4</td>
首先,我通过以下代码获取整行:
MatchCollection mPrevious = Regex.Matches(html, "<td class=\"previous\">\\s*(.*?)\\s*</td>", RegexOptions.Singleline);
其次,我使用以下代码仅提取数字:
foreach (Match m in mPrevious)
{
if (m.Groups[1].Value.Contains("span"))
{
string stringtemp = Regex.Match(m.Groups[1].Value, "-?\\d+.\\d+.\">-?\\d+.\\d+|-?\\d+.\\d+\">-?\\d+.\\d+|-?\\d+.\">-?\\d+|-?\\d+\">-?\\d+").Value;
int indextemp = stringtemp.IndexOf(">");
if (indextemp <= 0) break;
lPrevious.Add(stringtemp.Remove(0, indextemp + 1));
}
else lPrevious.Add(Regex.Match(m.Groups[1].Value, @"-?\d+.\d+|-?\d+").Value);
}
首先我开始确定是否存在SPAN标记,如果存在,我将两个数字放在一起,并且我已经考虑了与正则表达式不同的可能性。确定从哪里删除非重要信息的角色,并删除我不想要的内容。
它完美无瑕。
谢谢大家的支持和快速解答。