C# 基于相似性比较字符串
我有两张清单,它们看起来像这样C# 基于相似性比较字符串,c#,.net,regex,C#,.net,Regex,我有两张清单,它们看起来像这样 <List> ads [0] Headline = "Sony Ericsson Arc silver" [1] Headline = "Sony Ericsson Play R800I" <List> feedItems [0] Headline = "Sony Ericsson Xperia Arc Silver" [1] Headline = "Sony Ericsson Xperia Play R800i Black" [0]
<List> ads
[0]
Headline = "Sony Ericsson Arc silver"
[1]
Headline = "Sony Ericsson Play R800I"
<List> feedItems
[0]
Headline = "Sony Ericsson Xperia Arc Silver"
[1]
Headline = "Sony Ericsson Xperia Play R800i Black"
[0]
AdHeadline = "Sony Ericsson Arc silver"
MatchingFeed = "Sony Ericsson Xperia Arc Silver"
// etc
我已经尝试遍历第一个列表并使用了Regex.Match类,如果找到匹配项,我将填充第三个列表-我想知道您首选的方法是什么,以及如何检查表达式中至少2+个单词。有趣的问题。您可以通过多种方式解决此问题,但一个好主意可能是建立一个制造商列表,然后可以使用该列表从传入列表中删除字符串。然后为您关心的所有移动型号建立一个查找表,并在该表上使用型号和制造商(您之前已经确认)进行LINQ选择。因此,确定什么是制造商和型号可能会让事情变得更容易
就我个人而言,我不会使用regex,而是构建一个通用的phone模型类,然后您可以使用它创建一个列表。另外,如果输入了电话数据,则手工考虑使用< P>有趣的问题。您可以通过多种方式解决此问题,但一个好主意可能是建立一个制造商列表,然后可以使用该列表从传入列表中删除字符串。然后为您关心的所有移动型号建立一个查找表,并在该表上使用型号和制造商(您之前已经确认)进行LINQ选择。因此,确定什么是制造商和型号可能会让事情变得更容易
就我个人而言,我不会使用regex,而是构建一个通用的phone模型类,然后您可以使用它创建一个列表。另外,如果输入的电话数据是手动的,考虑使用 < P>,我不确定正则表达式会给聚会带来什么。下面呢
// Define a helper function to split a string into its words.
Func<string, HashSet<string>> GetWords = s =>
new HashSet<string>(
s.Split(new[]{' '}, StringSplitOptions.RemoveEmptyEntries)
);
// Pair up each string with its words. Materialize the second one as
// we'll be querying it multiple times.
var aPairs = ads.Select(a => new { Full = a, Words = GetWords(a) });
var fPairs = feedItems
.Select(f => new { Full = f, Words = GetWords(f) })
.ToArray();
// For each ad, select all the feeds that match more than one word.
// Then just select the original ad and feed strings.
var result = aPairs.SelectMany(
a => fPairs
.Where(f => a.Words.Intersect(f.Words).Skip(1).Any())
.Select(f => new { AdHeadline = a.Full, MatchingFeed = f.Full })
);
//定义一个helper函数,将字符串拆分为单词。
Func GetWords=s=>
新哈希集(
s、 拆分(新[]{''},StringSplitOptions.RemoveEmptyEntries)
);
//将每个字符串与其单词配对。将第二个具体化为
//我们将多次查询它。
var aPairs=ads.Select(a=>new{Full=a,Words=GetWords(a)});
var fPairs=馈线
.Select(f=>new{Full=f,Words=GetWords(f)})
.ToArray();
//对于每个广告,选择与多个单词匹配的所有提要。
//然后只需选择原始广告和提要字符串。
var result=aPairs.SelectMany(
a=>fPairs
.Where(f=>a.Words.Intersect(f.Words.Skip(1).Any())
.Select(f=>new{AdHeadline=a.Full,MatchingFeed=f.Full})
);
我不确定正则表达式是否能为这里的聚会带来什么。下面呢
// Define a helper function to split a string into its words.
Func<string, HashSet<string>> GetWords = s =>
new HashSet<string>(
s.Split(new[]{' '}, StringSplitOptions.RemoveEmptyEntries)
);
// Pair up each string with its words. Materialize the second one as
// we'll be querying it multiple times.
var aPairs = ads.Select(a => new { Full = a, Words = GetWords(a) });
var fPairs = feedItems
.Select(f => new { Full = f, Words = GetWords(f) })
.ToArray();
// For each ad, select all the feeds that match more than one word.
// Then just select the original ad and feed strings.
var result = aPairs.SelectMany(
a => fPairs
.Where(f => a.Words.Intersect(f.Words).Skip(1).Any())
.Select(f => new { AdHeadline = a.Full, MatchingFeed = f.Full })
);
//定义一个helper函数,将字符串拆分为单词。
Func GetWords=s=>
新哈希集(
s、 拆分(新[]{''},StringSplitOptions.RemoveEmptyEntries)
);
//将每个字符串与其单词配对。将第二个具体化为
//我们将多次查询它。
var aPairs=ads.Select(a=>new{Full=a,Words=GetWords(a)});
var fPairs=馈线
.Select(f=>new{Full=f,Words=GetWords(f)})
.ToArray();
//对于每个广告,选择与多个单词匹配的所有提要。
//然后只需选择原始广告和提要字符串。
var result=aPairs.SelectMany(
a=>fPairs
.Where(f=>a.Words.Intersect(f.Words.Skip(1).Any())
.Select(f=>new{AdHeadline=a.Full,MatchingFeed=f.Full})
);
肯定有更有效的方法来实现这一点,但这里有一些东西可以让您开始
class Program
{
private static void Main()
{
var ads = new[]
{
"Sony Ericsson Arc silver",
"Sony Ericsson Play R800I",
"Oneword",
};
var feedItems = new[]
{
"Sony Ericsson Xperia Arc Silver",
"Nokia Lumia 900",
"Sony Ericsson Xperia Play R800i Black",
};
var results = from ad in ads
from feedItem in feedItems
where isMatch(ad, feedItem)
select new
{
AdHeadline = ad,
MatchingFeed = feedItem,
};
foreach (var result in results)
{
Console.WriteLine(
"AdHeadline = {0}, MatchingFeed = {1}",
result.AdHeadline,
result.MatchingFeed
);
}
}
public static bool isMatch(string ad, string feedItem)
{
var manufacturerWords = new[] { "sony", "ericsson", "nokia" };
ad = ad.ToLower();
feedItem = feedItem.ToLower();
var adWords = Regex.Split(ad, @"\W+").Except(manufacturerWords);
var feedItemWords = Regex.Split(feedItem, @"\W+").Except(manufacturerWords);
var isMatch = adWords.Count(feedItemWords.Contains) >= 2;
return isMatch;
}
}
当然,有更有效的方法可以做到这一点,但这里有一些东西可以让你开始
class Program
{
private static void Main()
{
var ads = new[]
{
"Sony Ericsson Arc silver",
"Sony Ericsson Play R800I",
"Oneword",
};
var feedItems = new[]
{
"Sony Ericsson Xperia Arc Silver",
"Nokia Lumia 900",
"Sony Ericsson Xperia Play R800i Black",
};
var results = from ad in ads
from feedItem in feedItems
where isMatch(ad, feedItem)
select new
{
AdHeadline = ad,
MatchingFeed = feedItem,
};
foreach (var result in results)
{
Console.WriteLine(
"AdHeadline = {0}, MatchingFeed = {1}",
result.AdHeadline,
result.MatchingFeed
);
}
}
public static bool isMatch(string ad, string feedItem)
{
var manufacturerWords = new[] { "sony", "ericsson", "nokia" };
ad = ad.ToLower();
feedItem = feedItem.ToLower();
var adWords = Regex.Split(ad, @"\W+").Except(manufacturerWords);
var feedItemWords = Regex.Split(feedItem, @"\W+").Except(manufacturerWords);
var isMatch = adWords.Count(feedItemWords.Contains) >= 2;
return isMatch;
}
}
您还应考虑拼写错误和使用缩写的可能性。有完整的编程包专门用于这类事情。我同意罗琳的观点,正则表达式对这类问题没有任何用处。可能的重复也应该考虑拼写错误和缩写的使用。有完整的编程包专门用于这类事情。我同意罗林的观点,正则表达式对于这类问题没有任何用处。