【问题标题】:Matching only characters in sequence of a word from a given string仅匹配给定字符串中单词序列中的字符
【发布时间】:2012-06-15 09:12:19
【问题描述】:

我试图通过给出一个特定的字符串来为一个词找到最接近的匹配,例如:

所以我会:

"jonston" x "john"  => "jo" //only "jo" is the part that matches
"joshua" x "john" => "jo" 
"mark" x "marta"    => "mar"

如您所见,我只想检索序列匹配中的字符,这就是为什么 joshuajohn 只会在公共序列中使用 jo 而不是 joh,因为两者都有字母 h

我已经尝试使用以下正则表达式:

"john".match(/["joshua"]+/) //=> outputs ["joh"] and not ["jo"]

有什么方法可以只匹配匹配的第一个字符?

我将使用 javascript 来实现

我希望这是有道理的

提前致谢

【问题讨论】:

    标签: javascript regex string-matching charsequence


    【解决方案1】:
    initLCS = function(a, b) {
        for (var i = 0; i < a.length && a[i] == b[i]; i++);
        return a.substr(0, i);
    }
    
    
    initLCS("jonston", "john") // jo
    initLCS("jonston", "j111") // j
    initLCS("xx", "yy") // ""
    

    如果你坚持使用正则表达式,它是这样的:

    initLCS = function(a, b) {
    
        function makeRe(x) {
            return x.length ? "(" + x.shift() + makeRe(x) + ")?" : "";
        }
    
        var re = new RegExp('^' + makeRe(b.split("")), "g");
        return a.match(re)[0];
    }
    

    这会从第二个字符串创建一个类似/^(j(o(h(n)?)?)?)?/g 的表达式,并将其应用于第一个字符串。并不是说它有多大意义,只是为了它。

    【讨论】:

    • @sp00m:它本质上是你的,但更简洁。
    【解决方案2】:
    var a = "john";
    var b = "joshua";
    var x = "";
    
    for (var i = 0; i < a.length; i++) {
        if (x == "" && i > 0) break;
        else if (a[i] == b[i]) x += a[i];
        else if (x != "") break;
    }
    
    console.log(x);
    

    演示: http://jsfiddle.net/jMuDm/

    【讨论】:

    • 哦,不,我的错,逻辑读错了:p 但它不适用于 johnmariejoe
    • @FlorianMargaine 有什么办法可以只匹配第一个匹配的字符吗?
    • 我并没有说这回答了问题,我只是说这对johnmariejoe 不起作用,你回答它会。我只是想进一步推动这个算法:-)
    • @FlorianMargaine 是的,但它应该适用于johnmariejoe 吗?
    • 哦,好吧,假设我只是想获得一些工程乐趣。
    【解决方案3】:

    另一个解决方案:

    if(typeof String.prototype.commonFirstChars !== 'function') {
        String.prototype.commonFirstChars = function(s) {
            var common = "";
            for(var i=0; i<this.length; i++) {
                if(this[i] !== s[i]) {
                    return common;
                }
                common += this[i];           
            }
        };
    }
    

    你可以这样使用它:

    var commonFirstChars = "john".commonFirstChars("joshua");
    // "john".commonFirstChars("joshua") === "joshua".commonFirstChars("john")
    

    这将返回:

    jo

    【讨论】:

      【解决方案4】:

      你不能用正则表达式真正做到这一点。为什么不直接遍历两个字符串并比较索引?您可以选择字符,直到您在同一索引处找到具有不同值的字符。

      【讨论】:

        【解决方案5】:

        我会在这样的递归函数中执行此操作:

        编辑:更新示例使其更具可读性。

        var testWords = [
            ['ted', 'terminator'],
            ['joe', 'john'],
            ['foo', 'bar']
        ];
        
        var matches = testWords.map(function(wordPair) {
            return (function matchChars(word1, word2, matches) {
                if (word1[0] !== word2[0]) { 
                    return [wordPair[0], wordPair[1], matches];
                }
        
                matches = matches || '';
                matches += word1[0];
                return matchChars(word1.slice(1), word2.slice(1), matches);
            }(wordPair[0], wordPair[1]));
        });
        
        
        console.log(matches.map(function(match) { return match.join(', '); }).join('\n'));
        ​
        

        小提琴(更新): http://jsfiddle.net/VU5QT/2/

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-11-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-02-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多