1

I want to insert an ending slash before the closing bracket of every img tag found in a string.

This (modified from here) is correctly returning the position of each instance of img:

var re = /img\s/g,
    match;
    while (match = re.exec(str)) {
      console.log(match.index); //
    }

Knowing this, how can I find the next > after each imgand insert a / before it?

Community
  • 1
  • 1
Ila
  • 3,528
  • 8
  • 48
  • 76
  • 2
    Why would you need it ? – adeneo Dec 21 '13 at 23:11
  • Because I am passing the HTML string to a PHP application that wants XHTML, not HTML, and it's breaking on the img tags because they are unclosed. – Ila Dec 21 '13 at 23:13
  • Additionally: Yes, I am extremely sure that img tags will be the only self-closing tags that will ever appear in the string in question. – Ila Dec 21 '13 at 23:14
  • 1
    It seems you never learn: http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags?rq=1 – Silviu Burcea Dec 21 '13 at 23:16
  • 1
    Oh FFS. The second answer on that question specifies the occasional usefulness of regex with limited, known HTML. – Ila Dec 21 '13 at 23:21
  • For what it's worth, `` is a "void element" and doesn't need a closure: http://www.w3.org/TR/html-markup/syntax.html#void-element – Marc Dec 21 '13 at 23:36
  • I know, and for display purposes I wouldn't ever close it, but it needs to act like XHTML for this particular period of its lifecycle. – Ila Dec 21 '13 at 23:41

3 Answers3

4

How about this, it's simple but seems like it would work for your case:

str.replace(/(<img[^>]*)>/g, "$1 />");

if you wanted it to be a little more smart, you could do something like this:

str.replace(/(<img[^>]*?) *\/?>/g, "$1 />");

this would account for things that already have a space and/or a slash at the end... and create the same output for all of the following:

IN:
<img src='foo.png'>
<img src='foo.png' >
<img src='foo.png'/>
<img src='foo.png' />
OUT for all the above:
<img src='foo.png' />

if you would rather have <img src='foo.png'/>, just remove the space after $1 in the replace.

Smern
  • 18,746
  • 21
  • 72
  • 90
2

try something like this:

var imgs = "<img blblblb > <img adadasd>"
var pattern = /(<img[^>]*)>/g;

imgs = imgs.replace(pattern, "$1/>");
console.log(imgs);
//<img blblblb /> <img adadasd/>
klarki
  • 915
  • 4
  • 13
1

I have a non-regex solution, if you’re interested:

<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=ISO-8859-1"/>
<script type="text/javascript">
function close_img_tags(){
var str = document.getElementById("txt").value, len = str.length, i, j;
for(i = 0; i < len-4; i++){
    if(str[i]+str[i+1]+str[i+2]+str[i+3] == "<img"){
        for(j = i+4; j < len; j++){
            if(str[j] == ">"){
                if(str[j-1] != "/"){
                str = str.substr(0, j)+"/"+str.substr(j);
                i = j+2;
                }
                else{
                i = j+1;
                }
            break;
            }
        }
    }
}
document.getElementById("txt").value = str;
}
</script>
<style type="text/css">
textarea{
width:400px;
height:300px;
}
</style>
</head>
<body>
<textarea id="txt"></textarea><br/>
<button type="button" onclick="close_img_tags();">Edit HTML</button>
</body>
</html>

Demo: http://jsfiddle.net/eZu9U/