JS/Jquery:字符串到单词的文本分割脚本使用字典和最长匹配

JS/Jquery: string to words text-segmentation script using dictionary and longest match?

本文关键字:字典 脚本 分割 Jquery 字符串 文本 单词 JS      更新时间:2023-09-26

给定一个字符串,例如:

 var str = "thisisinsane";

由字典中的单词列表辅助,例如:

 var dic = [ "insane", "i", "is", "sin", "in", "this", "totally" ];

如何将str拆分为单词

对于这个字符串,有3个单词需要识别。但我们需要避免这些陷阱。为了在大多数时候避开它们,我知道我们可以从左边攻击这个句子,并试图找到最长的单词。当被发现时,我们可以攻击字符串的其余部分等。

下面是右下角的输入、可能的陷阱和想要的输出。

                      thisisinsane
                          |
                          |
                     (this)isinsane
                     /            '
                    /              '
          (this,i)sinsane         (this,is)insane
              /                     /           '
             /                     /             '
  (this,i,sin)ane          (this,is,in)sane    (this,is,insane)
                                /                   <BEST IS>
                               /                    <THIS ONE>
                       (this,is,in,sane)

最后,我们想要得到:

 var splited = ["this", "is", "insane"];

这是一个快速实现,它将从左到右进行搜索,并首先匹配字典中最长的单词(jsfiddle)。然而,我不太确定自己实现这一点是否明智,因为这听起来像是一个复杂的领域,即使在没有任何相关知识的情况下,我也可以看出这种算法一开始就有缺陷。如果有现有的库的话,你可能会更好地查找它们。

不用说,这只是打字很快。它没有以任何方式针对性能进行优化(它使用递归,这实际上根本没有必要),也没有经过广泛的测试。不过,它适用于您的示例数据,以及我测试的一些变体。我喜欢把一些工作留给OP,以防我给出完整的代码示例,所以如果你想使用它,请随时改进。

var splitByDictionary = function (input, dictionary) {
    "use strict";
    // make sure we're going to look for longest-possible matches first
    dictionary.sort( function (a, b) {
        return b.length - a.length;
    } );
    var foundWords = [],
        remaining = input;
    var result = (function match () {
        if( remaining.length === 0 ) {
            return true;
        }
        for( var i = 0; i < dictionary.length; i++ ) {
            if( remaining.substr( 0, dictionary[i].length ) === dictionary[i] ) {
                foundWords.push( dictionary[i] );
                remaining = remaining.substr( dictionary[i].length );
                return match();
            }
        }
        return false;
    })();
    return result ? foundWords : null;
};
var splitted = splitByDictionary( "thisisinsane", ["insane", "i", "is", "sin", "in", "this", "totally"] );
console.log( splitted ); // ["this", "is", "insane"]