重复组以形成对象

Repeat Groups to form objects

我有一个 html table 这样的:

<table style="width:100%">
  <tr>
    <td class="country">Germany</td>
  </tr>
  <tr>
    <td class="city">Berlin</td>
  </tr>
  <tr>
    <td class="city">Cologne</td>
  </tr>
  <tr>
    <td class="city">Munich</td>
  </tr>
   <tr>
    <td class="country">France</td>
  </tr>
  <tr>
    <td class="city">Paris</td>
  </tr>
      <tr>
    <td class="country">USA</td>
  </tr>
  <tr>
    <td class="city">New York</td>
  </tr>
  <tr>
    <td class="city">Las Vegas</td>
  </tr>
</table>

从这个 table,我想生成像 类 国家和城市这样的对象。国家/地区将有一个城市列表。

现在问题来了: 创建一个正则表达式来获取所有国家和所有城市很容易,但我想知道我是否可以让城市组重复直到下一个国家开始?我需要这样做,因为如果我将它们放在单独的正则表达式匹配中,我无法以编程方式弄清楚哪个城市属于哪个国家/地区。

它应该像(快速和肮脏的解决方案):

country">([\w]*)<{.*\n.*\n.*\n.*"city">([\w]*)}

大括号应重复出现,直到出现下一个国家/地区项目。

如果您对如何在 c# 中从 html table 中获取对象有完全不同的想法,请告诉我!

提前致谢!

同意对于任何重要的 HTML 应该使用像 HtmlAgilityPack 这样的 HTML 解析器。话虽如此,如果您的 HTML 与上面的代码片段一样简单,即使字符串中有多个换行符,这也是可行的:

string HTML = @"
<table style='width:100%'>
    <tr><td class='country'>Germany</td></tr>
    <tr><td class='city'>Berlin</td></tr>
    <tr><td class='city'>Cologne</td></tr>
    <tr><td class='city'>Munich</td></tr>
    <tr><td class='country'>France</td></tr>
    <tr><td class='city'>Paris</td></tr>
    <tr><td class='country'>USA</td></tr>
    <tr><td class='city'>New York</td></tr>
    <tr><td class='city'>Las Vegas</td></tr>
</table>";

var regex = new Regex(
    @"
        class=[^>]*?
        (?<class>[-\w\d_]+)
        [^>]*>
        (?<text>[^<]+)
        <
    ",
    RegexOptions.Compiled | RegexOptions.IgnoreCase 
    | RegexOptions.IgnorePatternWhitespace
);

var country = string.Empty;
var Countries = new Dictionary<string, List<string>>();
foreach (Match match in regex.Matches(HTML))
{
    string countryCity = match.Groups["class"].Value.Trim();
    string text = match.Groups["text"].Value.Trim();
    if (countryCity.Equals("country", StringComparison.OrdinalIgnoreCase))
    {
        country = text;
        Countries.Add(text, new List<string>());
    }
    else
    {
        Countries[country].Add(text);
    }
}