一个固定模式,后跟任意数量的其他模式使用正则表达式

时间:2015-01-12 10:57:50

标签: regex powershell html-parsing html-agility-pack regex-greedy

要求:我有以下数据与regEX匹配。我需要获得名称1,名称2,名称3和名称4。

某些条件:

  1. $regex需要考虑Name总是在<H2>Composition<\H2>之后
  2. 可能有任意数量的Name即可能在Composition之后只有一种模式说Name1或两种模式Name1Name2
  3. 撰写后至少会有一个Name模式。所以正则表达式应该像“组合存在然后Name1肯定会存在”
  4. 示例:

     <H2>Composition</H2>
     <A href="/generics/levocetrizine-210129">Name 1</A>,
     <A href="/generics/paracetamol-210459">Name 2(500 mg)</A>,
     <A href="/generics/phenylephrine-hydrochloride-210494">Name 3</A>,
     <A href="/generics/ambroxol-hydrochloride-211798">Name 4</A></DIV></DIV></DIV></DIV>
    

    到目前为止,我只能通过以下脚本获得第一个Name,即Name1。我的脚本只是忽略其余的“名称”,即在上面的情况下,我的输出中缺少Name2,Name3和Name4。

    [regex]$regex = 
    @'
    (?s).+?<H2>Composition</H2>.*?href="/generics/.*?">(.*?)</A>
    '@
    

1 个答案:

答案 0 :(得分:2)

使用XPath表达式或针对HTML Agility pack的一点C#,这个问题更容易解决。 Regular Expressions are going to be a major pain,但在这种情况下,您可以使它们有效。

使用HTML Agility Pack,它将类似于:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(yourString);

string xpath = "//H2[contains(text(), 'Composition')]/following-sibling::A[contains(@href, '/generics/']";

var nodes = doc.DocumentNode.SelectNodes(xpath);
foreach (var node in nodes)
{
    string name = node.InnerText;
    string uri = node.Attributes["href"].Value;
}

从这个小C#代码段转换为Powershell应该不会很难。

从长远来看,使用Regex将是一件痛苦的事情,它并不意味着对HTML或XML等结构化文档进行HTML解析或解析。

如果你真的想采取糟糕,糟糕,不好,可怕,正则表达式的方式,请尝试这样的事情:

(?i)<h2>composition</h2>(?:(?:(?!<a).*)<a href="/generics/[^"]+">(?<name>(?!</a).*)</A>)*

使用.NET正则表达式功能获取捕获:

([regex]$regex).Match("$content").Groups['name'].Captures