C# 比较字符串和缩写
C# Comparing strings to abbreviations
我正在尝试将完整字符串与其缩写版本进行比较,并return根据其相似性得出一个分数。
这是一个例子:
Quarta Vara Civel Santana de Parnaiba
以及可能的缩写
Qta VC Sta Parnaiba
Q V C Sta Pba
4 VC Sta Parnaiba
我尝试使用 FuzzyStrings dll 这样做,但是当涉及到像第二个和第三个示例这样的严重缩写时,它就不能正常工作了。
关于如何处理这个问题有什么想法吗?
使用 this answer 的 Jaro-Winkler 距离 class,它优先匹配前缀,并将每个缩写成分与短语单词进行比较(选择最大匹配以补偿跳过的单词) ,我们可以写这些扩展:
public static class StringExt {
public static double JaroWinklerDistance(this string s1, string s2) => JaroWinkler.proximity(s1, s2);
private static Regex AbbrevSplitRE = new Regex(@" |(?=\p{Lu})", RegexOptions.Compiled);
public static double AbbrevSimilarity(this string abbrev, string phrase) {
var phraseWords = phrase.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
return AbbrevSplitRE.Split(abbrev)
.Where(aw => !String.IsNullOrEmpty(aw))
.Zip(Enumerable.Range(0, phraseWords.Length),
(aw, pwp) => Enumerable.Range(pwp, phraseWords.Length-pwp).Select(n => aw.JaroWinklerDistance(phraseWords[n])).Max()
)
.Sum() / phraseWords.Length;
}
}
注意:正则表达式将缩写组件定义为每个 space 或大写字母。
然后,我们可以将每个缩写(在 abbrevs
中)与原始 phrase
进行比较:
var ans = abbrevs.Select(Abbrev => new { Abbrev, Similarity = Abbrev.AbbrevSimilarity(phrase) });
对于你的例子,我得到这个答案:
Abbrev | Similarity
Qta VC Sta Parnaiba | 0.65001322751322754
Q V C Sta Pba | 0.60371693121693126
4 VC Sta Parnaiba | 0.53890211640211649
我可能会为较短的缩写添加权重,具体取决于我的最终目的。
我正在尝试将完整字符串与其缩写版本进行比较,并return根据其相似性得出一个分数。
这是一个例子:
Quarta Vara Civel Santana de Parnaiba
以及可能的缩写
Qta VC Sta Parnaiba
Q V C Sta Pba
4 VC Sta Parnaiba
我尝试使用 FuzzyStrings dll 这样做,但是当涉及到像第二个和第三个示例这样的严重缩写时,它就不能正常工作了。
关于如何处理这个问题有什么想法吗?
使用 this answer 的 Jaro-Winkler 距离 class,它优先匹配前缀,并将每个缩写成分与短语单词进行比较(选择最大匹配以补偿跳过的单词) ,我们可以写这些扩展:
public static class StringExt {
public static double JaroWinklerDistance(this string s1, string s2) => JaroWinkler.proximity(s1, s2);
private static Regex AbbrevSplitRE = new Regex(@" |(?=\p{Lu})", RegexOptions.Compiled);
public static double AbbrevSimilarity(this string abbrev, string phrase) {
var phraseWords = phrase.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
return AbbrevSplitRE.Split(abbrev)
.Where(aw => !String.IsNullOrEmpty(aw))
.Zip(Enumerable.Range(0, phraseWords.Length),
(aw, pwp) => Enumerable.Range(pwp, phraseWords.Length-pwp).Select(n => aw.JaroWinklerDistance(phraseWords[n])).Max()
)
.Sum() / phraseWords.Length;
}
}
注意:正则表达式将缩写组件定义为每个 space 或大写字母。
然后,我们可以将每个缩写(在 abbrevs
中)与原始 phrase
进行比较:
var ans = abbrevs.Select(Abbrev => new { Abbrev, Similarity = Abbrev.AbbrevSimilarity(phrase) });
对于你的例子,我得到这个答案:
Abbrev | Similarity
Qta VC Sta Parnaiba | 0.65001322751322754
Q V C Sta Pba | 0.60371693121693126
4 VC Sta Parnaiba | 0.53890211640211649
我可能会为较短的缩写添加权重,具体取决于我的最终目的。