递归搜索字符串中的模式

时间:2012-11-30 13:19:07

标签: c# string

我正在使用c#。 我有以下字符串

<li> 
    <a href="abc">P1</a> 
    <ul>
        <li><a href = "bcd">P11</a></li>
        <li><a href = "bcd">P12</a></li>
        <li><a href = "bcd">P13</a></li>
        <li><a href = "bcd">P14</a></li>
    </ul>
</li>
<li> 
    <a href="abc">P2</a> 
    <ul>
        <li><a href = "bcd">P21</a></li>
        <li><a href = "bcd">P22</a></li>
        <li><a href = "bcd">P23</a></li>
    </ul>
</li>
<li> 
    <a href="abc">P3</a> 
    <ul>
        <li><a href = "bcd">P31</a></li>
        <li><a href = "bcd">P32</a></li>
        <li><a href = "bcd">P33</a></li>
        <li><a href = "bcd">P34</a></li>
    </ul>
</li>
<li> 
    <a href="abc">P4</a> 
    <ul>
        <li><a href = "bcd">P41</a></li>
        <li><a href = "bcd">P42</a></li>
    </ul>
</li>

我的目标是从上面的字符串中填写以下列表。

List<class1>

class1有两个属性,

string parent;
List<string> children;

它应填写父母的P1和儿童的P11,P12,P13,P14,并列出它们。

任何建议都会有所帮助。

修改

样品

public List<class1> getElements()
{
    List<class1> temp = new List<class1>();
    foreach(// <a> element in string)
    {
        //in the recursive loop
        List<string> str = new List<string>();
        str.add("P11");
        str.add("P12");
        str.add("P13");
        str.add("P14");

        class1 obj = new class1("P1",str);
        temp.add(obj);
    }
    return temp;
}

这里的值是硬编码的,但它是动态的。

3 个答案:

答案 0 :(得分:4)

你想要的是一个递归下降解析器。使用库的所有其他建议基本上都建议您使用由其他人编写的HTML或XML的递归下降解析器。

递归下降解析器的基本结构是对标记列表(在您的情况下为字符串)进行线性搜索,并在遇到分隔子实体的标记时再次调用解析器来处理标记子列表(子串)。

你可以谷歌使用术语“递归下降解析器”并找到大量有用的结果。在这种情况下,甚至维基百科的文章也相当不错,并且在C中包含了一个递归下降解析器的例子。

答案 1 :(得分:3)

如果您不能使用我推荐的Html Agility Pack之类的第三方工具,您可以使用Webbrowser类和HtmlDocument类来解析HTML:

WebBrowser wbc = new WebBrowser();
wbc.DocumentText = "foo"; // necessary to create the document
HtmlDocument doc = wbc.Document.OpenNew(true);
doc.Write((string)html); // insert your html-string here
List<class1> elements = wbc.Document.GetElementsByTagName("li").Cast<HtmlElement>()
    .Where(li => li.Children.Count == 2)
    .Select(outerLi => new class1
    {
        parent = outerLi.FirstChild.InnerText,
        children = outerLi.Children.Cast<HtmlElement>()
            .Last().Children.Cast<HtmlElement>()
            .Select(innerLi => innerLi.FirstChild.InnerText).ToList()
    }).ToList();

以下是调试器窗口中的结果:

enter image description here

答案 2 :(得分:1)

您也可以使用XmlDocument:

XmlDocument doc = new XmlDocument();
doc.LoadXml(yourInputString);
XmlNodeList colNodes = xmlSource.SelectNodes("li");
foreach (XmlNode node in colNodes)
{
    // ... your logic here
    // for example
    // string parentName = node.SelectSingleNode("a").InnerText;
    // string parentHref = node.SelectSingleNode("a").Attribures["href"].Value;
    // XmlNodeList children = 
    //       node.SelectSingleNode("ul").SelectNodes("li");
    // foreach (XmlNode child in children)
    // {
    //         ......
    // }
}