Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding the difference between two string in Javascript with regex [closed]

Regex experts please help to see if this problem can be solved by regex:

Given string 1 is any string

And string 2 is any string containing all parts of string 1 (but not a simple match -- I will give example)

How to use regex to replace all parts of string 1 in string 2 with blank so that what's remained is the string not in string 1?

For example: str1 = "test xyz"; str2 = "test ab xyz"

I want " ab" or "ab " back. What is the regex I can write so that when I run a replace function on str2, it will return " ab"?

Here is some non-regex code:

            function findStringDiff(str1, str2) {
                var compareString = function(str1, str2) {
                    var a1 = str1.split("");
                    var a2 = str2.split("");
                    var idx2 = 0;
                    a1.forEach(function(val) {
                        if (a2[idx2] === val) {
                          a2.splice(idx2,1);
                        } else {
                            idx2 += 1;
                        }
                    });
                    if (idx2 > 0) {
                        a2.splice(idx2,a2.length);
                    }
                    return a2.join("");
                }

                if (str1.length < str2.length) {
                    return compareString(str1, str2);
                } else {
                    return compareString(str2, str1);
                }
            }

            console.log(findStringDiff("test xyz","test ab xyz"));
like image 428
techguy2000 Avatar asked Apr 11 '15 03:04

techguy2000


2 Answers

Regexes only recognize if a string matches a certain pattern. They're not flexible enough to do comparisons like you're asking for. You would have to take the first string and build a regular language based on it to recognize the second string, and then use match groups to grab the other parts of the second string and concatenate them together. Here's something that does what I think you want in a readable way.

//assuming "b" contains a subsequence containing 
//all of the letters in "a" in the same order
function getDifference(a, b)
{
    var i = 0;
    var j = 0;
    var result = "";

    while (j < b.length)
    {
        if (a[i] != b[j] || i == a.length)
            result += b[j];
        else
            i++;
        j++;
    }
    return result;
}

console.log(getDifference("test fly", "test xy flry"));

Here's a jsfiddle for it: http://jsfiddle.net/d4rcuxw9/1/

like image 196
Millie Smith Avatar answered Nov 13 '22 07:11

Millie Smith


I find this question really interesting. Even though I'm a little late, I would like to share my solution on how to accomplish this with regex. The solution is concise but not very readable.

While I like it for its conciseness, I probably would not use it my code, because it's opacity reduces the maintainability.

var str1 = "test xyz",
    str2 = "test ab xyz"
    replacement = '';
var regex = new RegExp(str1.split('').map(function(char){
    return char.replace(/[.(){}+*?[|\]\\^$]/, '\\$&');
}).join('(.*)'));
if(regex.test(str2)){
    for(i=1; i<str1.length; i++) replacement = replacement.concat('$' + i);
    var difference = str2.replace(regex, replacement);
} else {
    alert ('str2 does not contain str1');
}

The regular expression for "test xyz" is /t(.*)e(.*)s(.*)t(.*) (.*)x(.*)y(.*)z/ and replacement is "$1$2$3$4$5$6$7".

The code is no longer concise, but it works now even if str1 contains special characters.

like image 28
Lorenz Meyer Avatar answered Nov 13 '22 09:11

Lorenz Meyer