llams48
llams48

Reputation: 407

Replacing a string unless its in a certain substring of given string

Given a long html string, I want to replace a string in the html unless it's within the <img> tags of the html.

For example, Input: text "here"<img src="img_url.jpg" width="100" height="100"></img>

I want to replace all occurrences of " with &quot; unless the quotes are within the <img> tags because that would break the urls.

Output: text &quot;here&quot;<img src="img_url.jpg" width="100" height="100"></img>

I am currently using input.replace(/"/g, "&quot;"), but that replaces all the quotes in the string. How do I replace everything except for that certain substring? I am not very experienced with regex, but I have figured out that I can detect the img tags using /<img[^>]+>/

Many thanks in advance for your help!

Upvotes: 1

Views: 98

Answers (2)

Amadan
Amadan

Reputation: 198314

Assuming that all attributes are valid (i.e. there is no < inside attributes, like <img comparison="a<2">):

var str = 'text "here"<img src="img_url.jpg" width="100" height="100"></img>';
str = str.replace(/(<.*?>)|"/g, function(m, m1) {
  if (m1) return m1;
  else return "&quot;";
});
snippet.log(str);
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

But, it would probably be safer to just make a DOM, then recurse through all text nodes and do a replacement locally, then serialize to HTML again. (EDIT ...as Arun P Johny just did, which I'll be upvoting).

Also, I figured it would be a bad idea to replace it in everything except in <img> tags, since then you would likely get things like <div class=&quot;red&quot;>.

Upvotes: 2

Arun P Johny
Arun P Johny

Reputation: 388316

It is always a bad idea to replace the contents of an html string using regex

var string = 'text "here"<img src="img_url.jpg" width="100" height="100"></img>';

var $tmp = $('<div />', {
  html: string
});

$tmp.find('*').addBack().contents().each(function() {
  if (this.nodeType == Node.TEXT_NODE) {
    this.nodeValue = this.nodeValue.replace(/"/g, '&quot;');
  }
});

var result = $tmp.html();
snippet.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<!-- To show result in the dom instead of console, only to be used in the snippet not in production -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

Upvotes: 2

Related Questions