最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Testing for a common word between 2 strings in javascript - Stack Overflow

programmeradmin0浏览0评论

I have to match 2 strings where at least one word is same, I need to give a success msg.

var str1 = "Hello World";
var str2 = "world is beautiful";

I need to match/pare these 2 strings, in both strings world is matching, So i need to print a success message. How do I go about it.

I have to match 2 strings where at least one word is same, I need to give a success msg.

var str1 = "Hello World";
var str2 = "world is beautiful";

I need to match/pare these 2 strings, in both strings world is matching, So i need to print a success message. How do I go about it.

Share Improve this question edited Nov 16, 2012 at 9:46 Phil H 20.2k8 gold badges71 silver badges105 bronze badges asked Nov 16, 2012 at 9:02 madhumadhu 1,0187 gold badges21 silver badges39 bronze badges 1
  • plete word or partial word? Should "worldly" match "world" or not? – Lee Kowalkowski Commented Nov 16, 2012 at 9:18
Add a ment  | 

6 Answers 6

Reset to default 3

The following code will output all the matching words in the both strings:

var words1 = str1.split(/\s+/g),
    words2 = str2.split(/\s+/g),
    i,
    j;

for (i = 0; i < words1.length; i++) {
    for (j = 0; j < words2.length; j++) {
        if (words1[i].toLowerCase() == words2[j].toLowerCase()) {
           console.log('word '+words1[i]+' was found in both strings');
        }
    }
}

You can avoid paring all the words in one list with all the words in the other by sorting each and eliminating duplicates. Adapting bjornd's answer:

var words1 = str1.split(/\s+/g),
    words2 = str2.split(/\s+/g);

var allwords = {};
// set 1 for all words in words1
for(var wordid=0; wordid < words1.length; ++wordid) {
    var low = words1[wordid].toLowerCase();
    allwords[low] = 1;
}
// add 2 for all words in words2
for(var wordid=0; wordid < words2.length; ++wordid) {
    var current = 0;
    var low = words2[wordid].toLowerCase();
    if(allwords.hasOwnProperty(low)) {
        if(allwords[low] > 1) {
            continue;
        }
    }
    current += 2;
    allwords[low] = current;
}
// now those seen in both lists have value 3, the rest either 1 or 2.
// this is effectively a bitmask where the unit bit indicates words1 membership
// and the 2 bit indicates words2 membership
var both = [];
for(var prop in allwords) {
    if(allwords.hasOwnProperty(prop) && (allwords[prop] == 3)) {
        both.push(prop);
    }
}

This version should be reasonably efficient, because we are using a dictionary/hash structure to store information about each set of words. The whole thing is O(n) in javascript expressions, but inevitably dictionary insertion is not, so expect something like O(n log n) in practise. If you only care that a single word matches, you can quit early in the second for loop; the code as-is will find all matches.

This is broadly equivalent to sorting both lists, reducing each to unique words, and then looking for pairs in both lists. In C++ etc you would do it via two sets, as you could do it without using a dictionary and the parison would be O(n) after the sorts. In Python because it's easy to read:

words1 = set(item.lower() for item in str1.split())
words2 = set(item.lower() for item in str2.split())
mon = words1 & words2

The sort here (as with any set) happens on insertion into the set O(n log n) on word count n, and the intersection (&) is then efficent O(m) on the set length m.

I just tried this on WriteCodeOnline and it works there:

var s1 = "hello world, this is me";
var s2 = "I am tired of this world and I want to get off";
var s1s2 = s1 + ";" + s2;
var captures = /\b(\w+)\b.*;.*\b\1\b/i.exec(s1s2);

if (captures[1])
{
   document.write(captures[1] + " occurs in both strings");
}
else
{
  document.write("no match in both strings");
}

Just adapting @Phil H's code with a real bitmask:

var strings = ["Hello World", "world is beautiful"]; // up to 32 word lists
var occurrences = {},
    result = [];
for (var i=0; i<strings.length; i++) {
    var words = strings[i].toLowerCase().split(/\s+/),
        bit = 1<<i;
    for (var j=0, l=words.length; j<l; j++) {
        var word = words[j];
        if (word in occurrences)
            occurrences[word] |= bit;
        else
            occurrences[word] = bit;
    }
}
// now lets do a match for all words which are both in strings[0] and strings[1]
var filter = 3; // 1<<0 | 1<<1
for (var word in occurrences)
    if ((occurrences[word] & filter) === filter)
        result.push(word);

OK, the simple way:

function isMatching(a, b)
{
  return new RegExp("\\b(" + a.match(/\w+/g).join('|') + ")\\b", "gi").test(b);
}

isMatching("in", "pin"); // false
isMatching("Everything is beautiful, in its own way", "Every little thing she does is magic"); // true
isMatching("Hello World", "world is beautiful"); // true

...understand?

I basically converted "Hello, World!" to the regular expression /\b(Hello|World)\b/gi

Something like this would also do:

isMatching = function(str1, str2) {
    str2 = str2.toLowerCase();
    for (var i = 0, words = str1.toLowerCase().match(/\w+/g); i < words.length; i++) {
        if (str2.search(words[i]) > -1) return true;
    } 
    return false;
};

var str1 = "Hello World";
var str2 = "world is beautiful";
isMatching(str1, str2); // returns true
isMatching(str1, 'lorem ipsum'); // returns false
发布评论

评论列表(0)

  1. 暂无评论