我希望匹配未包含在HTML锚点中的格式为foo:12345的所有文本。例如,我想匹配以下第1行和第3行:
foo:123456
<a href="http://www.google.com">foo:123456</a>
foo:123456
我试过这些正则表达式没有成功:
否定前瞻尝试(错误匹配,但不包括最后一位数字)
foo:(\d+)(?!</a>)
非捕获分组的负向前瞻
(?:foo:(\d+))(?!</a>)
负面的后视尝试(似乎不支持通配符)
(?<!<a[^>]>)foo:(\d+)
答案 0 :(得分:3)
如果您想开始像这样分析HTML,那么您可能希望实际解析HTML而不是使用正则表达式。 HTML Agility Pack是通常的第一个停靠点。使用正则表达式变得很难处理像<a></a>foo:123456<a></a>
这样的东西,当然这些东西应该拉出中间位,但是很难编写一个能够做到这一点的正则表达式。
我应该补充一点,我假设你确实有一块HTML而不是单独的短字符串,例如你上面的每一行。部分我把它排除了因为它匹配它如果它是唯一的线上很容易所以我想你已经得到它,如果你想要它。 :)
答案 1 :(得分:0)
正则表达式通常不是这项工作的最佳工具,但如果你的案例非常具体,你可以使用:
foo:((?>\d+))(?!</a>)
你的第一个表达不起作用,因为\d+
会回溯到(?!</a>)
匹配。这可以通过不允许\d+
回溯来解决,如上所述在原子/非回溯组的帮助下,或者您也可以在\d+
回溯的情况下使前瞻失败,例如:
foo:((?>\d+))(?!</a>|\d)
虽然效率不高。
答案 2 :(得分:0)
请注意,lookbehind不适用于内部不同的字符串长度,您可能会以不同的方式进行操作
例如
答案 3 :(得分: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 "<"
}
答案 4 :(得分: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