Javascript:模糊查找字符串中的子字符串

时间:2016-11-11 18:20:59

标签: javascript node.js

我有一组字符串,我需要模糊地查找这些字符串中是否包含其中一个字符串。如果是这样,我需要句子中子字符串的位置。 例如:

var input = "how was the whether in Londom last night?"; var set = ["london uk", "paris"]; fuzzyFind(input, set); // return something like {score: xxx, found: "london uk", start: 23, end: 29}

http://fusejs.io/可以做这样的事情,但除非我错过了它,否则它不会告诉我子字符串在输入字符串中的位置。

是否有现成的库(它将在Node中使用)?

1 个答案:

答案 0 :(得分:-1)

确保已设置include: ["matches"]选项。

编辑:那应该是include: ["score","matches"],然后在结果中每个结果对象都有一个“匹配”和一个“得分”属性。并且匹配将是每个项目键的“索引”列表,每个匹配项具有开始和结束位置。

另外,在我注意到这些选项在fuse.js之前我写过的答案是来自fuzzball.js(我的模糊模糊端口)和difflib的partial_ratio函数的一个版本,修改为包括较长字符串的最佳匹配子字符串及其开始/结束位置以及分数/比率。

从第二眼看,我的第一个答案并不完全是你想要的,而且无论如何都被低估了,我已经写好了,也就是这样:)

var difflib = require('difflib');

var input = "how was the whether in Londom last night?";
var set = ["london uk", "paris"];
console.log(topSubString(input, set));

/* 
[score, best matching substring, start, stop]

[ [ 0.5555555555555556, 'Londom la', 23, 32 ],
  [ 0.4, 'was t', 4, 9 ] ]
*/

function topSubString(input, set) {
    results = [];
    for (var s in set) {
        results.push(partial_ratio(input, set[s]));
    }
    results.sort(function (a, b) { return b[0] - a[0] })[0];
    return results;
}
function partial_ratio(str1, str2, options) {

    if (str1.length <= str2.length) {
        var shorter = str1
        var longer = str2
    }
    else {
        var shorter = str2
        var longer = str1
    }
    var bestMatch;
    var m = new difflib.SequenceMatcher(null, shorter, longer);
    var blocks = m.getMatchingBlocks();
    var scores = [];
    for (var b = 0; b < blocks.length; b++) {
        var long_start = (blocks[b][1] - blocks[b][0]) > 0 ? (blocks[b][1] - blocks[b][0]) : 0;
        var long_end = long_start + shorter.length;
        var long_substr = longer.substring(long_start, long_end);
        var ssm = new difflib.SequenceMatcher(null, shorter, long_substr);
        var r = ssm.ratio(shorter, long_substr, options);
        if (r > 99.5) { bestMatch = [r, long_substr, long_start, long_end]; break; }
        else scores.push([r, long_substr, long_start, long_end]);
    }
    if (!bestMatch) bestMatch = scores.sort(function(a,b){ return b[0] - a[0] })[0];
    return bestMatch;
}