0

Suppose that one has:

  • an element object element.
  • a regular expression or a simple string pattern.
  • a string replacement (this can be a simple string or one with replacement tokens).

In JavaScript, without invoking jQuery or a JavaScript library, how can one safely replace all of the occurrences of pattern with replacement in the child text nodes of element? How can one achieve this if replacement also contains markup instead of text that will be escaped if it contains less-than signs or greater-than signs? The problem with using element.innerHTML = element.innerHTML.replace(pattern, replacement) is that it can potentially break markup. So, using that to replace a hyperlink's displayed text could change the address the hyperlink points to.

The answer can contain can contain two solutions: one that replaces text with text (i.e., "<" in replacement would be treated as &lt;) and one that replaces text with literal of the string (i.e., <br/> in replacement would be treated as <br/> instead of &lt;br/&gt;). Alternatively, the answer may contain only one solution that, like the second solution in the first option, treats < and > as < and >, respectively.

Melab
  • 2,594
  • 7
  • 30
  • 51
  • 4
    This sounds like a homework question. – ceejayoz Jan 07 '17 at 02:36
  • 1
    Do a search on `childNodes` and how to determine which ones are text nodes (hint: `nodeType`). – mseifert Jan 07 '17 at 02:40
  • Do not attempt to parse HTML with a regular expression, see [*this answer*](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). – RobG Jan 07 '17 at 04:23

1 Answers1

0

I would change all of the < and >s first then you can check for br. You need to use the g flag at the end of your expressions to make them greedy. I put optional spaces and a forward slash option in there too. Have fun... and try to make your JavaScript XHTML friendly so it's transportable.

// external.js
var pre = onload, doc, bod, htm, E, stripMost; // keeping vars above the onload allows for use on other pages - change pre to different var name if using technique on another page
onload = function(){
if(pre)pre(); // execute previous onload if exists
  
doc = document; bod = doc.body; htm = doc.documentElement;
E = function(id){
  return doc.getElementById(id);
}
stripMost = function(inputString){
  return inputString.replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/&lt;\s*br\s*\/?s*&gt;/g, '<br />');
}
var so = E('so'); // works like document.getElementById('so')
so.onclick = function(){
  E('out').innerHTML = stripMost(E('in').value);
}

}
/* external.css */
#in{
  width:200px; height:25px; border:1px solid #000;
}
#so{
  height:25px;
}
<!DOCTYPE html>
<html xmlns='http://www.w3.org/1999/xhtml' xml:lang='en' lang='en'>
  <head>
    <meta http-equiv='content-type' content='text/html;charset=utf-8' />
    <link type='text/css' rel='stylesheet' href='external.css' />
    <script type='text/javascript' src='external.js'></script>
  </head>
<body>
  <input type='text' id='in' /> <input type='button' id='so' value='show output' />
  <div id='out'></div>
</body>
</html>
StackSlave
  • 10,613
  • 2
  • 18
  • 35
  • 3
    Do not attempt to parse HTML with a regular expression, see [*this answer*](http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). See mseifert's comment for how to go about it. – RobG Jan 07 '17 at 04:25
  • That is the craziest Stack Overflow page I've ever seen. At least it made me laugh. `.innerHTML` and `.value`s are Strings, therefore fine for RegEx's. – StackSlave Jan 07 '17 at 04:51
  • It's an odd question, since it seems to want to arbitrarily decide whether to treat "<" and ">" as parts of tags or plain characters, which indicates some kind of parsing that is more complex than provided by a regular expression. – RobG Jan 07 '17 at 05:13