3

例如:

S1: "some filename contains few words.txt"
S2: "some filename contains few words - draft.txt"
S3: "some filename contains few words - another draft.txt"
S4: "some filename not contains few words.txt"

需要注意的是,我可以获得第一个字符串的 S2 或 S3 以及其他匹配的字符串。

编辑:我有“主”字符串,我需要找到匹配项。

可以说,在第一轮中,我发现了错别字。

现在我只需要匹配整个单词。

我希望能够确定 7 个单词中有 5 个匹配,或者 10 个单词中有 7 个匹配。“X out of Y”的确切数量不太重要。

重要的是如何找到不同的 X 个单词,无论它们在句子中的哪个位置。

谢谢

4

2 回答 2

7

这不是正则表达式问题。

你不指定语言,但如果你使用 java,有getLevenshteinDistanceStringUtils 的方法。从javadocs:

求两个字符串之间的 Levenshtein 距离。

这是将一个字符串更改为另一个字符串所需的更改次数,其中每次更改都是单个字符修改(删除、插入或替换)。

用法:

int distance = StringUtils.getLevenshteinDistance(
    "some filename contains few words.txt",
    "some filename not contains few words.txt"
);

要匹配某个百分比,您必须确定哪个字符串是“主”字符串,因为输入字符串可以有不同的长度:distance可能都是删除,所以"cat""cataract"的距离为5. 定义“90% 匹配”应该是什么也有点困难。看看我们的cat例子;100% 的字符串“cat”出现在“cataract”中,但它们不是完全相同的字符串。您必须根据您的用例来决定这些规则。

更新

如果您的“差异”应该是基于单词的,那么在单词边界上拆分字符串并Map从结果单词构造 a 到每个单词的计数会相对容易。比较每个字符串生成的地图应该会给你一个粗略的“相似性”测量。例如:

public HashMap<String, Integer> countWords(String str) {
    HashMap<String, Integer> counts = new HashMap<String, Integer>();
    for(String s : str.split("\\s+")) {
        if(!s.isEmpty()) {
            if(counts.containsKey(s)) {
                counts.put(s, counts.get(s) + 1);
            } else {
                counts.put(s, 1);
            }
        }
    }
    return counts;
}

// ...

String s1 = "some filename contains few words.txt";
String s2 = "some filename not contains few words.txt";
HashMap<String, Integer> s1Counts = countWords(s1);
HashMap<String, Integer> s2Counts = countWords(s2);
// assume s1 is "master" string, count the total number of words
int s1Total = 0, s2Total = 0;
for(Integer i : s1Counts.values()) {
    s1Total += i;
}
// iterate over words in s1, find the number of matching words in s2
for(Map.Entry<String, Integer> entry : s1Counts.entrySet()) {
    if(s2Counts.containsKey(entry.getKey())) {
        if(s2Counts.get(entry.getKey()) >= entry.getValue()) {
            s2Total += entry.getValue();
        } else {
            s2Total += s2Counts.get(entry.getKey());
        }
    }
}
// result
System.out.println(s2Total + " out of " + s1Total + " words match.");
于 2012-06-20T07:30:14.917 回答
1

我认为值得一提的是看一下 Apache commons-text 类JaroWinklerDistance

Find the Jaro Winkler Distance which indicates the similarity score between two CharSequences.
 distance.apply(null, null)          = IllegalArgumentException
 distance.apply("","")               = 0.0
 distance.apply("","a")              = 0.0
 distance.apply("aaapppp", "")       = 0.0
 distance.apply("frog", "fog")       = 0.93
 distance.apply("fly", "ant")        = 0.0
 distance.apply("elephant", "hippo") = 0.44
 distance.apply("hippo", "elephant") = 0.44
 distance.apply("hippo", "zzzzzzzz") = 0.0
 distance.apply("hello", "hallo")    = 0.88
 distance.apply("ABC Corporation", "ABC Corp") = 0.93
 distance.apply("D N H Enterprises Inc", "D & H Enterprises, Inc.") = 0.95
 distance.apply("My Gym Children's Fitness Center", "My Gym. Childrens Fitness") = 0.92
 distance.apply("PENNSYLVANIA", "PENNCISYLVNIA")    = 0.88
于 2018-09-26T20:16:35.387 回答