regex 用于匹配HTML中有序列表项元素的正则表达式

vkc1a9a2  于 2023-04-13  发布在  其他
关注(0)|答案(1)|浏览(114)

我想要一个正则表达式(最好用C#)匹配所有列表项元素标记(<li>),位于***有序列表***元素中(<ol>)。我不希望匹配列表项的文本表示,仅匹配开始标签,并且理解可能不存在结束标签。也可能存在属性,例如style属性。
HTML代码示例:

<div>
<ul>
<li>Apple
<li>Banana
<li style=color:red>Cherry
</ul>
<ol>
<li>Avocado
<li>Beetroot
<li style=color:orange>Carrot
</ol>
<ul>
<li>Test Item A</li>
<li>Test Item B</li>
<li>Test Item C</li>
</ul>
<ol>
<li>Test Item 1</li>
<li>Test Item 2</li>
<li>Test Item 3</li>
</ol>
</div>

因此,我希望Avocado、Beetroot和Carrot项目元素开始标记(而不是内部文本)匹配,并且测试项目1、测试项目2和测试项目3项目元素也匹配。但是,我不希望任何其他项目元素匹配,因为它们在无序列表(<ul>)中。
应该有6个匹配结果:

<li>
<li>
<li style=color:orange>
<li>
<li>
<li>

请注意,我 * 不 * 需要结束标记(</li>,如果有的话)匹配。
我知道列表可以嵌套(一个列表嵌套在另一个列表中),但我现在只是在寻找一些简单的东西。
我不太精通正则表达式,我尝试过很多组合。我尝试的最后一个表达式,我使用了look behind和look forward功能:
在一个简单的(尽管不完整)版本中,我能够获得有序列表中的第一个项目,但不能获得其余项目:

(?<=<ol>)[^<]*<li[^>]*>

然后我尝试了以下操作,但没有找到匹配项:

(?<=<ol>)[^<]*<li[^>]*>(?=</ol>)

我也理解使用正则表达式的安全含义。但是,由于我正在开发一个屏幕阅读应用程序,这应该不是问题。

0ejtzxu1

0ejtzxu11#

你可以试试这个正则表达式模式:

(?:<ol>\s*)((?<group_li><li[^>]*>)[^<]*(</li>)?\s+)+(?:\s*</ol>)

使用组模式(?<group_li><li[^>]*>)olli元素的每个开放标记捕获到命名组group_li
下面是打印所有匹配的li元素的示例代码片段

string input = @"<div>
               <ul>
               <li>Apple
               <li>Banana
               <li style=color:red>Cherry
               </ul>
               <ol>
               <li>Avocado
               <li>Beetroot
               <li style=color:orange>Carrot
               </ol>
               <ul>
               <li>Test Item A</li>
               <li>Test Item B</li>
               <li>Test Item C</li>
               </ul>
               <ol>
               <li>Test Item 1</li>
               <li>Test Item 2</li>
               <li>Test Item 3</li>
               </ol>
             </div>";
Regex expression = new Regex(@"(?:<ol>\s*)((?<group_li><li[^>]*>)[^<]*(</li>)?\s+)+(?:\s*</ol>)");

// get all matches 
MatchCollection matches = expression.Matches(input);

// print all matched li
foreach (Match match in matches) {
    foreach (var li in match.Groups["group_li"].Captures) {
        Console.WriteLine(li);
    }
}

参见演示here

相关问题