0

I am new to both JavaScript and Regular Expression. I have a simple task to replace a series of <%whatever%> into (whatever) within the web page. Somehow regExp works in certain conditions only.

I am not sure if I've got the Expression wrong or the way I try to access document.body.HTML wrong. Please note the "works" and "not working" remarks within the code.

<html>
<head>
  <script>
  </script>
</head>
<body>
  Hello, my items are <%abc%>, <%efg%>, <%hik%><p/>
  <p/>
</body>
<script>
var Transform = function() {
    var regExp = /<%\^?\w+?\.?\w+?%>/gi;
    document.body.innerHTML = document.body.innerHTML.replace(/Hello/g,"Hi"); //works
    document.body.innerHTML = document.body.innerHTML.replace(/my/g,"your"); //works
    document.body.innerHTML = document.body.innerHTML.replace(/\<%/g,"("); //not working
    document.body.innerHTML = document.body.innerHTML.replace(/%\>/g,")"); //not working
    return;
}
teststr="<%abc%>";
teststr=teststr.replace(/\<%/g,"(");
teststr=teststr.replace(/%\>/g,")"); //works show as (abc)
console.log(teststr)
Transform();
</script>
</html>
1
  • @siam: no, % isn't a regex special character. (< and > too) Commented Feb 15, 2017 at 19:42

3 Answers 3

1

There are a number of problems with the code:

  • <%abc%> (and the other ones) are converted to text, because they are illegal HTML tags. So when you look at document.body.innerHTML, you see things like &lt;%abc%&gt; instead. You can get around this by using .innerText insetad of .innerHTML, depending on the specifics of what you need to do.
  • Anything after the opening <body> tag will be shoved into the body tag. So your script is also part of .innerHTML. To fix this, you could add your script in the <head> and set window.onload to run your code after the body has been set up. Alternatively you could put your content in a <div> within the body and do your replace on that.
  • You are getting .innerHTML 4 times, which could cause problems later down the line. You could instead operate on the same string and set .innerHTML once.

<html>
<head>
  <script>
  console.clear()
var Transform = function() {
    var regExp = /<%\^?\w+?\.?\w+?%>/gi;
    document.body.innerHTML = document.body.innerHTML
      .replace(/Hello/g,"Hi") //works
      .replace(/my/g,"your") //works
      .replace(/&lt;%/g,"(") //now working!!
      .replace(/%&gt;/g,")"); //now working!!
    return;
}

    window.onload = Transform;
  </script>
</head>
<body>
  Hello, my items are <%abc%>, <%efg%>, <%hik%><p/>
  <p/>
</body>
</html>

If something doesn't work, start from the point closest to the part not working and step backwards through the code. Log things to the console (console.log) to make sure values are as you expect. Make sure your code is running in the correct order, log values after you've logged them--things like that.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I also discover that the key is to use &gt; and &lt; instead of < and >. As you said, it has to do that HTML contents are encoded instead of straight text, which is in the case of text stored in the variable.
0

I think this is what you want

const data = `<p></p><% <b>here is some text</b> %>
  <% you probably want to do something more %>
  <% x = 2 * 2 ?%>` // inner html

const parse = (data) => data.replace(/<(?:%|&lt;)((?:\n|.)*?)(?:%|&gt;)>/g, data => {
  // calc value to replace here
  return data
})

// here is just replacement
const parse2 = (data) => data.replace(/<(?:%|&lt;)((?:\n|.)*?)(?:%|&gt;)>/g, '$1')

console.log(parse2(data))

Comments

0

That happens because when we talk about innerHTML, browser interprets < as &lt; and > as &gt;

So you need to modify your regular expression as in following demo.

var teststr = document.body.innerHTML;
teststr = teststr.replace(/&lt;%/g,"(");
teststr = teststr.replace(/%&gt;/g,")");
console.log(teststr);
<body>
  Hello, my items are <%abc%>, <%efg%>, <%hik%>
</body>

Important : Getting innerHTML of body will also include your script (if you've noticed that script is printing in console). So better is that you should avoid that and use querySelectors instead or put script in <head> section.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.