我在C#中使用多行正则表达式时出现问题,我该如何解决这个问题?

时间:2017-08-16 09:11:45

标签: c# regex

我有以下代码尝试提取li标签的内容。

        string blah = @"<ul>
        <li>foo</li>
        <li>bar</li>
        <li>oof</li>
        </ul>";

        string liRegexString = @"(?:.)*?<li>(.*?)<\/li>(?:.?)*";
        Regex liRegex = new Regex(liRegexString, RegexOptions.Multiline);
        Match liMatches = liRegex.Match(blah);
        if (liMatches.Success)
        {
            foreach (var group in liMatches.Groups)
            {
                Console.WriteLine(group);
            }
        }
        Console.ReadLine();

正则表达式开始变得更简单,没有多行选项,但我一直在调整它以试图让它工作。

我想要结果foobaroof,而是获得<li>foo</li>foo

除此之外,我似乎在Regex101中工作正常,https://regex101.com/r/jY6rnz/1

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

我首先要说的是,我认为如评论中所提到的,您应该使用适当的HTML解析器(例如HtmlAgilityPack)解析HTML。继续实际回答你的问题......

问题是你得到一个匹配,因为liRegex.Match(blah);只返回一个匹配。你想要的是liRegex.Matches(blah),它会返回所有的匹配。

所以你的用途是:

var liMatches = liRegex.Matches(blah);
foreach(Match match in liMatches)
{
    Console.WriteLine(match.Groups[1].Value);
}

答案 1 :(得分:2)

blah匹配时,您的正则表达式会生成多个匹配项。方法Match仅返回第一个匹配项,即foo个匹配项。您正在第一场比赛中打印所有组。这将得到1.整场比赛2.比赛的第1组。

如果您想获得foobar,那么您应该打印每个匹配的第1组。为此,您应首先使用Matches获取所有匹配项。然后迭代MatchCollection并打印Groups[1]

string blah = @"<ul>
<li>foo</li>
<li>bar</li>
<li>oof</li>
</ul>";
string liRegexString = @"(?:.)*?<li>(.*?)<\/li>(?:.?)*";
Regex liRegex = new Regex(liRegexString, RegexOptions.Multiline);
MatchCollection liMatches = liRegex.Matches(blah);
foreach (var match in liMatches.Cast<Match>())
{
    Console.WriteLine(match.Groups[1]);
}