【问题标题】:REGEX the HREF information and count from matches正则表达式 HREF 信息和匹配计数
【发布时间】:2017-09-27 08:10:29
【问题描述】:

我正在尝试确定我的 C# 脚本中 href 属性的数量。 下面是我从 StreamReader 返回并传递给 var (responsefromserver) 的 HTML

<html>
<head><title>Index of /file-download/isin/20170917/</title></head>
<body bgcolor="white">
<h1>Index of /file-download/isin/20170917/</h1><hr><pre><a 
href="../">../</a>
<a href="Commodities/">Commodities/</a>                                       
18-Sep-2017 00:05                   -
<a href="Credit/">Credit/</a>                                            
18-Sep-2017 00:05                   -
<a href="Equity/">Equity/</a>                                            
18-Sep-2017 00:05                   -
<a href="Foreign_Exchange/">Foreign_Exchange/</a>                                  
18-Sep-2017 00:05                   -
<a href="Rates/">Rates/</a>                                             
18-Sep-2017 00:05                   -
</pre><hr></body>
</html>

我想做的是获得一个匹配项(使用正则表达式),这样我就可以计算 URL 中 href 的数量(这些数量最多可以从 1 到 5 个不等。(商品、信用、股票、外汇和利率)然后我可以将计数传递给一个变量以供以后使用。

href 的名称永远不会改变,但我需要确认计数,然后我可以检查下载的文件计数是否与 href 的计数匹配(每个href 下都有一个文件)。

我的正则表达式技能很垃圾,我永远无法仅在条款(商品、信贷、股票、外汇和利率)上匹配,所以任何帮助建立这些字符串都会很棒。

任何指导都会很棒,我不是 C# 大用户,我在 SSIS 包中使用它,我使用 HTMLAgilityPack,所以如果有另一种方式比我更干净/更好开放的建议。我可以使用的任何代码 sn-ps,它给了我我需要的东西,使用 XPath 会很方便,因为我不是普通的 c# 用户(还)

非常感谢。

【问题讨论】:

  • 首先:不要使用 Regex 解析 HTML(您已经提到了 HTML Agility Pack - 使用它并通过 XPath 找到您需要的东西)。 “所以我可以计算 URL 中 href 的数量”是什么意思
  • 我知道这会是回应!我会把它放在下巴上,然后开始研究 Xpath。我所说的计数是指 URL 可以具有从 1 个属性到 5 个属性的任何属性,具体取决于可用的文件,我想计算其中的内容
  • 绝佳选择;)。我知道 Regex 可能很诱人,但这可能是“如果您遇到问题并尝试使用 Regex 解决它,您最终会遇到两个问题”的经典示例。

标签: c# html regex


【解决方案1】:

首先你必须声明你想要匹配的字符串

string[] toMatch = {"Rates","Foreign_Exchange","Equity","Credit","Commodities"};

带有 href 属性的链接的 Xpath 是 "//a[@href]"
要知道 Href 是否在您想要与您匹配的列表中:

toMatch.Any(myHrefValue.Contains)

产生如下代码:

var doc = new HtmlDocument();
doc.LoadHtml(input);
string[] toMatch = {"Rates","Foreign_Exchange","Equity","Credit","Commodities"};
var result = doc.DocumentNode
                .SelectNodes("//a[@href]")
                .Select(tag => tag.Attributes["href"].Value)
                .Where(link => toMatch.Any(s => link.Contains(s)));

您现在拥有所有匹配的 Href。一个简单的.Count() 是您需要的最后一步。

【讨论】:

  • 你可以直接使用Count扩展方法来代替Where( ... Any( ) )
  • @thehennyy,是的,只需将Where 替换为Count 即可,但我这样做有两个原因:1/。我觉得它更具可读性,并想展示 Where 子句。 2/。我不想立即将预期结果作为示例代码给出。
  • 哇,太棒了,真的很有帮助。我注意到一件事,这就是我回到正则表达式的原因(我知道那很糟糕)......当我尝试类似的代码时,我永远无法让“SelectNodes”工作。我收到一个错误“对象不包含对 SelectNodes 的引用......”。我有一个 HTMLAgilityPack 的命名空间。但它不会在存在 SelectNodes 时构建,我是否必须将其转换为使用 Linq?
  • 能否提供导致 rue 错误的 rue 代码。也许你没有在正确的对象上调用它
  • 代码如上,简单拖拽到我的代码中
【解决方案2】:

使用正则表达式作为 SSIS 似乎有限制。 你应该使用这样的模式:href="(Commodities|Credit|Equity|Foreign_Exchange|Rates)\/".

string pattern = @"href=""(Commodities|Credit|Equity|Foreign_Exchange|Rates)\/""";
var result = Regex.Matches(input, pattern).Count;

如果您需要从 db 构建模式:

string[] toMatch = { "Rates", "Foreign_Exchange", "Equity", "Credit", "Commodities" };
string pattern2  = @"href=""("+String.Join("|", toMatch)+@")\/""";

问题是如果您无法控制 Html 输入。因为这将匹配 Any Href 不仅是链接。像这样的正则表达式:&lt;a.*href="(Commodities|Credit|Equity|Foreign_Exchange|Rates)\/"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-10
    • 2011-05-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    相关资源
    最近更新 更多