C#正则表达式 - 获取第二个数字,而不是第一个

时间:2015-07-13 14:23:58

标签: c# regex

我有以下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 是否有一些正则表达技巧可以说,我想要句子中的第二个数字而不是第一个?

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);

结果:enter image description hereenter image description here

您不必担心内部格式化标记以及任何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");

enter image description here

如果您只需要获取特定标签,

如果您的文字内部有数字,而您只需要数字,则可以使用正则表达式:

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标记,如果存在,我将两个数字放在一起,并且我已经考虑了与正则表达式不同的可能性。确定从哪里删除非重要信息的角色,并删除我不想要的内容。

它完美无瑕。

谢谢大家的支持和快速解答。