我正在努力找出字符串列表中的常见字符串部分。如果我们取一个样本数据集
private readonly List<string> Xpath = new List<string>()
{
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(1)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(2)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(3)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(4)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(5)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(6)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(7)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(8)>H2:nth-of-type(1)",
"BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>SECTION:nth-of-type(9)>H2:nth-of-type(1)"
};
从这里,我想找出哪些孩子是相似的。data是Xpath列表。通过编程,我应该能够告诉
预期输出:
BODY>主要:nth-of-type(1)祝辞DIV> SECTION> DIV> SECTION> DIV> DIV: nth-of-type(1)祝辞DIV> DIV: nth-of-type(3)祝辞DIV> ARTICLE> DIV> DIV> DIV
为了得到这个我是这样做的。我用>
分隔每个项目,然后为每个数据集创建一个项目列表。
然后使用这个找出哪些是唯一项
private IEnumerable<T> GetCommonItems<T>(IEnumerable<T>[] lists)
{
HashSet<T> hs = new HashSet<T>(lists.First());
for (int i = 1; i < lists.Length; i++)
{
hs.IntersectWith(lists[i]);
}
return hs;
}
能够找出唯一值并重新创建数据集。但是发生的事情是,如果这包含Ex:- Div在两个地方,它也在每个原始数据集,即使这样,这个方法将只拾取一个Div。
从那里我将得到像这样的东西:
BODY>主要:nth-of-type(1)祝辞DIV>部分
但我需要这个
BODY>主要:nth-of-type(1)祝辞DIV> SECTION> DIV> SECTION> DIV> DIV: nth-of-type(1)祝辞DIV> DIV:的-式(3)祝辞DIV> ARTICLE>DIV> DIV> DIV
免责声明:这不是最有效的解决方案,但它可以工作:)
- 让我们从用
>
字符 分隔第一个路径开始 - 对所有路径 执行相同操作
char separator = '>';
IEnumerable<string> firstPathChunks = Xpath[0].Split(separator);
var chunks = Xpath.Select(path => path.Split(separator).ToList()).ToArray();
- 遍历
firstPathChunks
- 遍历
chunks
- 如果有匹配,则删除第一个元素
- 如果所有的第一个元素被删除,那么将匹配的前缀附加到
sb
- 遍历
void Process(StringBuilder sb)
{
foreach (var pathChunk in firstPathChunks)
{
foreach (var chunk in chunks)
{
if (chunk[0] != pathChunk)
{
return;
}
chunk.RemoveAt(0);
}
sb.Append(pathChunk);
sb.Append(separator);
}
}
样本使用
var sb = new StringBuilder();
Process(sb);
Console.WriteLine(sb.ToString());
输出
BODY>MAIN:nth-of-type(1)>DIV>SECTION>DIV>SECTION>DIV>DIV:nth-of-type(1)>DIV>DIV:nth-of-type(3)>DIV>ARTICLE>DIV>DIV>DIV>
通过分隔符>
解析字符串是个好主意。而不是创建唯一项的列表,而是创建字符串中包含的所有项的列表,这将导致
{
"BODY",
"MAIN:nth-of-type(1)",
"DIV",
"SECTTION",
"DIV",
...
}
表示XPath列表的第一个条目。
这样就创建了一个List<List<string>>
,其中包含XPath列表中每个条目的每个元素。然后可以比较内部列表的所有第一个元素。如果它们相等,则将该元素的值保存到输出中,然后继续处理所有第二个元素,以此类推,直到在所有外部列表中找到一个不相等的元素。
编辑:用>
分隔符分隔列表后,它可能看起来像这样:
List<List<string>> XPathElementsLists;
List<string> resultElements = new List<string>();
string result;
XPathElementsLists = ParseElementsFormXPath(XPath);
for (int i = 0; i < XPathElementsLists[0].Count; i++)
{
bool isEqual = true;
string compareElemment = XPathElementsLists[0][i];
foreach (List<string> element in XPathElementsLists)
{
if (!String.Equals(compareElemment, element))
{
isEqual = false;
break;
}
}
if (!isEqual)
{
break;
}
resultElements.Add(compareElemment);
}
result = String.Join(">", resultElements.ToArray());