views:

300

answers:

4

I am trying to wrap my head around using regular expressions and replace() with JavaScript, but have not yet been successful

Suppose I have a string containing this:

<img alt="a picture of ..." src="image/1533?foo=1&bar=2$zot=3" width="500" />

If zot=3 I want remove foo (and its value) (or replace foo=x with an empty string).

The replacement would look like this:

<img alt="a picture of ..." src="picture/1533?bar=2$zot=3" width="500" />

I want it to be as bullet-proof as possible as I can never be sure which order the URL parameters will be given in.

Is this possible using a single regex, or are there better solutions?

I was thinking of using DOM and

  • traversing all img nodes
  • get the src attribute
  • do a test if @src value has zot=3
  • if it has zot=3, replace foo=1 with an empty string

Of course I have to make sure that any ampersand and so on is removed too.

But I hope to resolve it using a regex or two,

Thanks for any and all answers and advice!

+1  A: 
var el = document.getElementsByTagName("img");
for(var i=0;i<el.length;i++)
{
  if(el.src.match(/zot=3/))
    el.src = el.src.replace(/(?<=[?&])foo=[^&]+&?/, '');
}

Untested - but should do what you are looking for.

The regexp:

  • (?<=[?&]) - zero width look behind - match a string starting after a ? or &
  • foo=[^&]+ - match 'foo=' followed by any number of non & characters.
  • &? - optionally match a & if it exists

Replace the matched string with nothing to remove the parameter.

gnarf
So a global String.replace is not recomended?
el.src is a String - it has the .replace() method inherited through the prototype chain. Not sure what you mean by "global String.replace()"
gnarf
Well, sorry, my description is a bit wrong. I found that I do not have a XML/HTML document, but only a string, meaning that DOM may be not an option.I would then have to make the string to a XML fragment (I think JavaScript can do this) but I hope to not code to much around this.
What is the purpose of this string? I was assuming you would be inserting this string into the DOM. After you insert it - it would be parseable using the getElementsByTagName. Why would you need to do anything before inserting?
gnarf
I am using TinyMCE (http://tinymce.moxiecode.com/examples/full.php) an online html editor.It has view HTML source functionality which let's me modify the document source (HTML button in the toolbar)The HTML view part is just a textarea. The HTML view does a getContent which transform the content in the document editor to a string and loads it to the textarea. What I am trying to do is to replace my img/@src values before the content is loaded to the HTML view.Beforer the string is loaded to the HTML view(textarea) I need to replace my src value.
A: 
var el = document.getElementsByTagName("img");
for(var i=0;i<el.length;i++)
{
  if(el.src.match(/zot\=3/i))
      el.src=el.src.replace(/foo\=.+?\&/i, "&");
}
Tolgahan Albayrak
+1  A: 

What gnarf said, except that JavaScript doesn't support regex lookbehinds (at least my IE and FF JavaScript implementations don't, or I'm copying and pasting wrong), so I can't test it as written without an exception. So I broke the expression in two to handle the distinct cases of:

1) beginning with ?, in which case ? is preserved but a following & is not, and

2) beginning with &, in which case the leading & is not preserved but a following & is.

While at it, I removed the expectation that foo= will be followed by anything, other than possibly a & starting the next parameter. Note also that there's little forgiveness for whitespace.

el.src = el.src.replace(/(\?)foo=[^&]*&?|&foo=[^&]*(&?)/, '$1$2');

I tested it with these src strings:

"image/1533?foo=1&bar=2$zot=3"
"image/1533?foo=&bar=2$zot=3"
"image/1533?bar=2$zot=3&foo=1"
"image/1533?bar=2$zot=3&foo="
"image/1533?bar=2$zot=3&foo=1&another=123"
"image/1533?bar=2$zot=3&foo=&another=123"

And got these results:

"image/1533?bar=2$zot=3"
"image/1533?bar=2$zot=3"
"image/1533?bar=2$zot=3"
"image/1533?bar=2$zot=3"
"image/1533?bar=2$zot=3&another=123"
"image/1533?bar=2$zot=3&another=123"

Good luck!

ewbi
A: 

This was just what I needed, thanks:

if(el.src.match(/zot=3/))
    el.src = el.src.replace(/(?<=[?&])foo=[^&]+&?/, '');