2012-06-15 1 views
2

Я пытаюсь найти ближайший матч за слово, давая определенную строку, например:Matching только символы в последовательности слова из заданной строки

, так что я бы:

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

, как вы можете видеть, что я только хотел бы получить символы в последовательности согласования, поэтому joshua и john только бы jo в общей последовательности и не joh, так как есть в письме h

Я пытался что с регулярным выражением, используя следующее:

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

есть ли способ, которым я мог бы соответствовать только первые символы, которые соответствуют?

Я буду использовать JavaScript для реализации

Я надеюсь, что имеет смысл

Заранее спасибо

ответ

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 из второй строки и применяет его к первому. Не то чтобы это имело смысл, просто для этого.

+0

Nice one, +1 :) – sp00m

+0

@ sp00m: это по существу ваше, но более сжатое. – georg

0

Вы не можете сделать это с помощью регулярных выражений. Почему вы просто не зацикливаете ни одну строку и не сравниваете индексы? Вы можете выбрать символы, пока не нажмете символ с тем же индексом с другим значением.

1
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); 

DEMO:http://jsfiddle.net/jMuDm/

+0

предоставит 'joh'. –

+0

@FlorianMargaine, как получилось? – VisioN

+0

О, нет, плохо, читайте логику неправильно: p Это не будет работать для 'john' и' mariejoe', хотя –

0

Я хотел бы сделать это в рекурсивной функции, как это:

EDIT: Изменено пример, чтобы сделать его более удобным для чтения.

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')); 
​ 

Fiddle (обновлено):http://jsfiddle.net/VU5QT/2/

1

Еще одно решение:

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