是否有可能找出字符串列表中共同的部分?



我正在努力找出字符串列表中的常见字符串部分。如果我们取一个样本数据集

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());

相关内容

最新更新