3

Lets say I have a string of words and phrases like this.

var a = "Apple Book \"Grand Piano\" Piano";

And I have a few variables like this.

var b = "Piano";
var c = "Grand Piano";

How do I remove variable b or c from string a. Currently i've been using javascripts replace method like this.

a = a.replace(b,"")

The problem with this is that it will remove the word Piano from the phrase "Grand Piano" when I only want it to remove the word Piano outside the quotes. I've been trying to use RegExp to get to some sort of solution but have been unable to figure it out. I was thinking I could possibly split the string up into an array and then compare the variables a/b in a for loop and then remove where they match and then put the string back together, not sure if that would be the best way. If someone could guide me in the right direction i'd be very gratefull.

Thank you.

dcrui3
  • 33
  • 3
  • 1
    I need some clarification on your replacement rules. Do you see `Grant Piano` as one word (because of the quotes)? So `Apple` and `Book` are separate words. Is this correct? If so, your language is **not** regular, and you can't use Regular Expressions. – Halcyon Aug 29 '13 at 15:33
  • You can order the terms to be removed by size first... maybe. – d'alar'cop Aug 29 '13 at 15:33
  • Yes, Grand Piano is seen as one word and Apple and Book are seperated as words aswell. – dcrui3 Aug 29 '13 at 15:36
  • have you tried a.replace(a || b, "")? – peterchon Aug 29 '13 at 15:40

3 Answers3

2

There was something a bit similar some days ago and you can adapt it to your case:

Piano(?!(?:[^"]*"[^"]*")*[^"]*"[^"]*$)

JSFiddle demo

The regex basically makes sure that there are no odd number of quotes ahead of the string to be replaced.

You can of course change the regex to accept variables instead of only Piano.

Community
  • 1
  • 1
Jerry
  • 70,495
  • 13
  • 100
  • 144
1

Using a simple parser:

var words = [];
var string = "Apple Book \"Grand Piano\" Piano";
var remove_word = "Piano";

// -- tokenize input --

var i, char, looking_for_quote = false, word = "";
for (i = 0; i < string.length; i += 1) {
    char = string[i];
    if (char === " " && looking_for_quote === false) {
        words.push(word);
        word = "";
    } else if (char === "\"" && looking_for_quote === false) {
        looking_for_quote = true;
    } else if (char === "\"" && looking_for_quote === true) {
        looking_for_quote = false;
    } else {
        word += char;
    }
}
words.push(word);   // dont forget the last word

console.log(words); // gives ["Apple", "Book", "Grand Piano", "Piano"]

// -- remove words --

while (words.indexOf(remove_word) !== -1) {
    words.splice(words.indexOf(remove_word), 1);
}

// reassemble output string

var out = []
for (i = 0; i < words.length; i += 1) {
    word = words[i];
    if (word.indexOf(" ") !== -1) {
        out.push("\"" + word + "\"");
    } else {
        out.push(word);
    }
}
console.log(out.join(" ")); // 'Apple Book "Grand Piano"'
Halcyon
  • 57,230
  • 10
  • 89
  • 128
  • This also works perfectly but for the simple one line solution I went with Jerry's answer. Thanks for doing this though. – dcrui3 Aug 29 '13 at 15:50
0
var a = "Apple Book \"Grand Piano\" Piano Pear";
var b = "Piano";
var c = "Grand Piano";
var regexp = new RegExp('('+b+')|('+c+')', 'g');
a = a.replace(regexp, '');

You need to do all the replacements simultaneously, with a regexp that matches everything you need to exclude. Make sure to escape your strings before adding them to the RegExp if it's needed.

Tibos
  • 27,507
  • 4
  • 50
  • 64