为什么 C# 的 Regex.Matches() 在单个 Match 对象中返回所有匹配项?
Why is C#'s Regex.Matches() returning all matches in a single Match object?
我在 C# 中通过正则表达式从 html 文本获取所有 <script>
及其各自的结束 </script>
标签时遇到问题。
我创建了一个示例 html,看起来像:
<html>
<head>
<title>
</title>
<script src="adasdsadsda.js"></script>
</head>
<body>
<script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
</body>
<script></script>
</html>
我使用的正则表达式是:
<script.*>[^>]*<\/script>
我经常使用 regexr 到 validate/test 我的正则表达式(强烈推荐!)。它显示有问题的正则表达式捕获了 3 次(正如我预期的那样)。
但是 C# 的 regex.Matches
没有捕获 3 个实例,而是捕获其中包含所有事件的单个实例。这是 Matches
方法的预期行为吗?我一直在使用它很多次,并将所有事件作为单独的捕获。
为什么我的情况会发生这种情况?
P.S:在回答问题时,如果你想指出正则表达式不适合解析HTML,请解释为什么regexr和.NET 的正则表达式给出不同的结果?他们有不同的正则表达式实现吗?
RegExr 使用浏览器的 RegExp 引擎进行匹配。它实现了不同的正则表达式风格。
.net uses a unique regex flavor, so I'd suggest using a .net 在线测试人员。例如:
但是,模式 <script.*>[^>]*<\/script>
应该 return 几乎所有风格的相同匹配文本。
代码
string pattern = @"<script.*>[^>]*<\/script>";
var re = new Regex( pattern);
var text = @"
<html>
<head>
<title>
</title>
<script src=""adasdsadsda.js""></script>
</head>
<body>
<script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
</body>
<script></script>
</html>
";
MatchCollection matches = re.Matches(text);
for (int mnum = 0; mnum < matches.Count; mnum++)
{ //loop matches
Match match = matches[mnum];
Console.WriteLine("Match #{0} - Value: {1}", mnum + 1, match.Value);
}
输出
Match #1 - Value: <script src="adasdsadsda.js"></script>
Match #2 - Value: <script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
Match #3 - Value: <script></script>
就是说,如果您在 JavaScript 代码中有 >
登录(作为 IF 条件的一部分或在字符串中),它将失败。
不使用正则表达式解析 HTML 的原因有很多,因此请采纳以下建议:不要使用正则表达式。 相反,您可以使用 HTML 敏捷包(1). edit: Instead, I recommend using a HTML parser.
我将 Mariano 的答案标记为解决方案,但我将进一步研究的结果留在这里,所选答案中未提及:
似乎最受欢迎的选项是(按受欢迎程度排序)以下 nuget 包:
- Html 敏捷包
- CsQuery
- 锐角
我最终使用了 AngleSharp,它比 CsQuery 的优势仍然是 maintained/developed。
我在 C# 中通过正则表达式从 html 文本获取所有 <script>
及其各自的结束 </script>
标签时遇到问题。
我创建了一个示例 html,看起来像:
<html>
<head>
<title>
</title>
<script src="adasdsadsda.js"></script>
</head>
<body>
<script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
</body>
<script></script>
</html>
我使用的正则表达式是:
<script.*>[^>]*<\/script>
我经常使用 regexr 到 validate/test 我的正则表达式(强烈推荐!)。它显示有问题的正则表达式捕获了 3 次(正如我预期的那样)。
但是 C# 的 regex.Matches
没有捕获 3 个实例,而是捕获其中包含所有事件的单个实例。这是 Matches
方法的预期行为吗?我一直在使用它很多次,并将所有事件作为单独的捕获。
为什么我的情况会发生这种情况?
P.S:在回答问题时,如果你想指出正则表达式不适合解析HTML,请解释为什么regexr和.NET 的正则表达式给出不同的结果?他们有不同的正则表达式实现吗?
RegExr 使用浏览器的 RegExp 引擎进行匹配。它实现了不同的正则表达式风格。
.net uses a unique regex flavor, so I'd suggest using a .net 在线测试人员。例如:
但是,模式 <script.*>[^>]*<\/script>
应该 return 几乎所有风格的相同匹配文本。
代码
string pattern = @"<script.*>[^>]*<\/script>";
var re = new Regex( pattern);
var text = @"
<html>
<head>
<title>
</title>
<script src=""adasdsadsda.js""></script>
</head>
<body>
<script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
</body>
<script></script>
</html>
";
MatchCollection matches = re.Matches(text);
for (int mnum = 0; mnum < matches.Count; mnum++)
{ //loop matches
Match match = matches[mnum];
Console.WriteLine("Match #{0} - Value: {1}", mnum + 1, match.Value);
}
输出
Match #1 - Value: <script src="adasdsadsda.js"></script>
Match #2 - Value: <script type='javascript'>
var a = 1 + 2;
alert('a');
</script>
Match #3 - Value: <script></script>
就是说,如果您在 JavaScript 代码中有 >
登录(作为 IF 条件的一部分或在字符串中),它将失败。
不使用正则表达式解析 HTML 的原因有很多,因此请采纳以下建议:不要使用正则表达式。 相反,您可以使用 HTML 敏捷包(1). edit: Instead, I recommend using a HTML parser.
我将 Mariano 的答案标记为解决方案,但我将进一步研究的结果留在这里,所选答案中未提及:
似乎最受欢迎的选项是(按受欢迎程度排序)以下 nuget 包:
- Html 敏捷包
- CsQuery
- 锐角
我最终使用了 AngleSharp,它比 CsQuery 的优势仍然是 maintained/developed。