I have the following jQuery snippet which should replace a code such as [Button] Text Here [/Button] into something like:
<a class="button">Text Here</a>
The javascript I have is the following:
$(document).ready(function() {
var buttonStart = $("body").html().replace(/\[Button\]*/ig,'<a class="button">');
$("body").html(buttonStart);
var buttonEnd = $("body").html().replace(/\[\/Button\]*/ig,'</a>');
$("body").html(buttonEnd);
});
The problem I am having is that it keeps replacing other elements on my page which have nothing to do with the Tags [Button] [/Button]. For insance the following:
<div id="MiddleBarLeft"></div>
Also gets replaced into
<a class="button"><div id="MiddleBarLeft"></div></a>
Shouldn’t the Regex I have above just look for [Button] and [/Button] Tags?
Also, is there any other efficient way to go about this?
Thanks
=====================
Update.. this is my entire HTML file which replaces elements that have nothing to do with what I want to replace
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type='text/javascript'>
$(document).ready(function() {
var buttonStart = $("body").html().replace(/\[Button\]/ig,'<a class="button">');
$("body").html(buttonStart);
var buttonEnd = $("body").html().replace(/\[\/Button\]/ig,'</a>');
$("body").html(buttonEnd);
});
</script>
<style>
li{
list-style:none;
padding-top:10px;
padding-bottom:10px;}
.button, .button:visited {
background: #222 url(overlay.png) repeat-x;
display: inline-block;
padding: 5px 10px 6px;
color: #fff;
text-decoration: none;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
border-bottom: 1px solid rgba(0,0,0,0.25);
position: relative;
cursor: pointer
}
</style>
</head>
<body>
<div>
<ul>
<li>[Button]Test[/Button]</li>
<li></li>
<li>Sample Text</li>
</ul>
</div>
</body>
</html>
The problem stems from the way the replacement occurs – please consider the following fiddle:
http://jsfiddle.net/GYrYa/
As you can see there are two buttons in the end, even though there’s only one [Button][/Button] statement – it’s because first you’re replacing [Button] with
<a class='button'>which creates an unmatched tag. This causes an</a>to be added at the end. Then you’re replacing [/Button] with</a>, which creates another unmatched tag – this time<a>, at the end.A better solution would be this:
http://jsfiddle.net/GYrYa/1/
EDIT: http://jsfiddle.net/GYrYa/2/ to omit script tag matching
EDIT 2: http://jsfiddle.net/GYrYa/5/ – final solution, incorporating @Rain Diao non-greedy matching
EDIT 3: Added performance test cases: http://jsperf.com/eithed-rsc3, please read the discussion below @Rain Diao’s answer for the genesis of it