【问题标题】:Regex "\d+" selector selecting digits one by one正则表达式“\d+”选择器一一选择数字
【发布时间】:2018-07-05 12:19:22
【问题描述】:

我创建了一个需要过滤的字符串的小样本:

https://regex101.com/r/PvXRiC/1

我想从下面的 html 中获取“61”:

<p class="b-list__count__number">
<span>61</span>/
<span>18786</span>
</p>

从我的示例中可以看出,“([\d+])”选择器选择了 6,而 1 是不同的匹配:

有什么方法可以在单场比赛中获得“61”吗?

【问题讨论】:

标签: c# html regex


【解决方案1】:

您的正则表达式不起作用,因为.* 是一个贪婪的点模式,它一次匹配整行,然后开始回溯,试图容纳一些应该由后续子模式匹配的文本。因此,只有最后一位作为\d+ 落在第二个捕获组中,才能匹配1 位。

虽然您可以通过使用 .*?a safer [^&lt;]*? 使 .* 变得懒惰来解决此问题,但您不应使用正则表达式来解析 HTML。

使用HtmlAgilityPack,例如:

var html = "<p class=\"b-list__count__number\">\n<span>61</span>/\n<span>18786</span>\n</p>";
HtmlAgilityPack.HtmlDocument hap;
Uri uriResult;
if (Uri.TryCreate(html, UriKind.Absolute, out uriResult))
{ // 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 node = hap.DocumentNode.SelectSingleNode("//p[@class='b-list__count__number']");
if (node != null)
{
    Console.Write(node.SelectSingleNode("//span").InnerText); // => 61
}

//p[@class='b-list__count__number'] 是一个 XPath 表达式,它获取具有 class 属性的 p 节点,该属性具有 b-list__count__number 值。 node.SelectSingleNode("//span").InnerText 获取找到的p 节点的第一个span 子节点的内部文本。

【讨论】:

    【解决方案2】:

    您的正则表达式(&lt;p class="b-list__count__number"&gt;\n&lt;span&gt;.*)([\d+]) 中的问题是.* 是贪婪的,并且除了最后一位之外,所有数字都被占用。您可以使用[^\d]* 停在第一位。

    (<p class="b-list__count__number">\n<span>[^\d]*)(\d+)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      相关资源
      最近更新 更多