2012-01-04 171 views
1

我正在寻找匹配HTML锚点中未包含的所有格式为foo:12345的文本。例如,我想从以下匹配线1和3:c#正则表达式来匹配特定文本

foo:123456

<a href="http://www.google.com">foo:123456</a>

foo:123456

我已经试过这些正则表达式没有成功:

负面预测尝试(错误匹配,但不包括最后一位数字)

foo:(\d+)(?!</a>)

负先行与非捕获分组

(?:foo:(\d+))(?!</a>)

负回顾后尝试(通配符似乎不支持)

(?<!<a[^>]>)foo:(\d+)

+0

我假设你的最后一个例子意思是'(?] *>)foo:(\ d +)',这样它将在锚标记中匹配多于一个字符。 – Chris 2012-01-04 18:15:27

+0

几乎每天都会问这个问题......用正则表达式解析HTML几乎总是[坏主意](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self -contained-tags) – 2012-01-04 18:28:36

回答

0

正则表达式通常不是最好的该工作的工具,但如果你的情况是非常具体的,就像在你的例子中,你可以使用:

foo:((?>\d+))(?!</a>) 

您的第一个表达式不起作用,因为\d+会回溯到(?!</a>)匹配。这可以通过不允许\d+原路返回,如以上的原子量/ nonbacktracking组的帮助下被固定,或者你也可以让先行的情况下,\d+回溯失败,如:

foo:((?>\d+))(?!</a>|\d) 

本书虽然是效率不高。

+0

将此标记为答案,因为它确实修正了正则表达式的工作原理 – dherman 2012-01-04 19:13:51

0

。注意,回顾后不会与不同的充字符串长度内工作,可以工作了不同

例如

  1. 找到和标记中包含的锚所有FOO-S
  2. 查找并与所有其他
  3. 删除标记
3

如果你想要做的第一你的目标艺术分析这样的HTML然后你可能想要实际解析HTML而不是使用正则表达式。 HTML Agility Pack是通常的第一停靠港。使用正则表达式很难处理像<a></a>foo:123456<a></a>这些当然应该拉出中间位但很难编写正则表达式的东西。

我应该补充一点,我假设你确实有一块HTML,而不仅仅是单个的短字符串,比如你上面的每一行。部分我排除它因为匹配它,如果它是唯一的行是非常容易的,所以我想你会得到它,如果你想这样做。:)

+0

这是一个很好的观点 - 我将研究如何使用该lib。谢谢。 – dherman 2012-01-04 19:15:02

0

这是一个概率长篇大论这样的方式,但你可以简单地带回FOO的所有出现:一些数字则排除他们事后..

string pattern = @"foo:\d+ |" + 
       @"foo:\d+[<]"; 

然后使用matchcollection

MatchCollection m0 = Regex.Matches(file, pattern, RegexOptions.Singleline); 

然后通过每次出现循环:

foreach (Match m in m0) 
{ 
       . . . exclude the matches that contain the "<" 
} 
0

我会使用LINQ和治疗HTML,如XML,例如: var query = MyHtml.Descendants()。ToArray(); 的foreach(的XElement结果查询) {

  if (Regex.IsMatch(result.value, @"foo:123456") && result.Name.ToString() != "a") 
      { 
       //do something... 
      } 
     } 

也许有更好的方式,但我不知道这...这似乎相当直截了当给我:P