代码之家  ›  专栏  ›  技术社区  ›  kakopappa

javascript字符串匹配模式帮助

  •  6
  • kakopappa  · 技术社区  · 15 年前

    我需要使用JavaScript找到几个单词或匹配的模式。

    这是要求。

    我有一根这样的绳子,

    这是下一个的快速指南 到了你最喜欢的油和其他话题的时候了

    我需要把这根绳子和这样的绳子配对

    favorite oil and some other topics can be based on something blah blah
    

    如何获得匹配文本块的交集?

    我已经尝试了intersect javascript脚本函数,对于一些字符串,它不能正常工作。

    如何解决这个问题?这可以用regex来完成吗?

    请教。

    3 回复  |  直到 8 年前
        1
  •  8
  •   Anurag    15 年前

    你必须找到 Longest common substring .

    如果字符串不是很长,我建议使用Tim的方法。否则,这是一个使用动态编程的最长通用子串算法的javascript实现。运行时为o(m n),其中m和n分别是2个字符串的长度。

    示例用法:

    var first = "Here is a quick guide for the next time you reach for your favorite oil and some other topics";
    var second = "favorite oil and some other topics can be based on something blah blah";
    
    console.log(first.intersection(second)); // ["favorite oil and some other topic"]
    

    这是算法实现。它返回最长公共子字符串的数组。扩展了本机字符串类,因此Intersect方法可用于所有字符串。

    String.prototype.intersection = function(anotherString) {
        var grid = createGrid(this.length, anotherString.length);
        var longestSoFar = 0;
        var matches = [];
    
        for(var i = 0; i < this.length; i++) {
            for(var j = 0; j < anotherString.length; j++) {
                if(this.charAt(i) == anotherString.charAt(j)) {
                    if(i == 0 || j == 0) {
                        grid[i][j] = 1;
                    }
                    else {
                        grid[i][j] = grid[i-1][j-1] + 1;
                    }
                    if(grid[i][j] > longestSoFar) {
                        longestSoFar = grid[i][j];
                        matches = [];
                    }
                    if(grid[i][j] == longestSoFar) {
                        var match = this.substring(i - longestSoFar + 1, i);
                        matches.push(match);
                    }
                }
            }
        }
        return matches;
    }
    

    还需要这个助手函数来创建一个二维数组,所有元素都初始化为0。

    // create a 2d array
    function createGrid(rows, columns) {
        var grid = new Array(rows);
        for(var i = 0; i < rows; i++) {
            grid[i] = new Array(columns);
            for(var j = 0; j < columns; j++) {
                grid[i][j] = 0;
            }
        }
        return grid;
    }
    
        2
  •  3
  •   Tim Down    13 年前

    这不是很有效,一般来说,有更好的方法可以做到这一点(请参见@anurag的答案),但它很简单,适用于短字符串:

    function stringIntersection(str1, str2) {
        var strTemp;
    
        // Swap parameters if necessary to ensure str1 is the shorter
        if (str1.length > str2.length) {
            strTemp = str1;
            str1 = str2;
            str2 = strTemp;
        }
    
        // Start with the whole of str1 and try shorter substrings until
        // we have a common one
        var str1Len = str1.length, l = str1Len, start, substring;
        while (l > 0) {
            start = str1Len - l;
            while (start >= 0) {
                substring = str1.slice(start, l);
                if (str2.indexOf(substring) > -1) {
                    return substring;
                }
                start--;
            }
            l--;
        }
        return "";
    }
    
    var s1 = "Here is a quick guide for the next time you reach"
           + " for your favorite oil and some other topics";
    var s2 = "favorite oil and some other topics can be based on"
           + " something blah blah";
    
    alert( stringIntersection(s1, s2) );
    
        3
  •  0
  •   Brian    8 年前

    一个简单的多填充过滤器字符串

    if (!String.prototype.intersection) {
      String.prototype.intersection = function(anotherString, caseInsensitive = false) {
        const value = (caseInsensitive) ? this.toLowerCase()          : this;
        const comp  = (caseInsensitive) ? anotherString.toLowerCase() : anotherString;
        const ruleArray = comp.split("").reduce((m,v) => {m[v]=true; return m;} ,{})
        return this.split("").filter( (c, i) => ruleArray[value[i]] ).join("")
      }
    }
    

    “HelloWorld”.交集(“Hewolrllodo”,真)

    “HelloWorld”-不区分大小写

    “地狱世界”。交叉口(“Hewollodo”)

    “Howo”-区分大小写