views:

93

answers:

5

How to replace all HTML tags from <anything> to \n<anything> and </anything> to <anything>\n

var text = "<anything>welcome</anything><anything>Hello</anything>";

result

var text = "\n<anything>welcome</anything>\n\n<anything>Hello</anything>\n";

This code will help you (match all tags)

</?\w+((\s+\w+(\s*=\s*(?:".*?"|'.*?'|[^'">\s]+))?)+\s*|\s*)/?>
+3  A: 

Just don't parse HTML using regex. Read this: http://www.codinghorror.com/blog/2009/11/parsing-html-the-cthulhu-way.html

In JavaScript, you can turn HTML into DOM using the .innerHTML property, and after that you can use other DOM methods to traverse it.

Simple example (needs Firebug):

var div = document.createElement('div');
var html = '<p>foo <span>bar</span><br /></p>';
div.innerHTML = html;

function scan(node, depth) 
{
    depth = depth || 0;
    var is_tag = node.nodeType == 1; 
    var self_contained = false;
    if (is_tag) {
        self_contained = node.childNodes.length == 0;
        var tag_name = node.tagName.toLowerCase();
        console.log('<' + tag_name + (self_contained ? ' /' : '') + '>', depth);
    } else {
        console.log(node.data); 
    }
    for (var i = 0, n = node.childNodes.length; i < n; i++) {
        scan(node.childNodes[i], depth + 1);
    }
    if (!self_contained && is_tag) {
        console.log('</' + tag_name + '>', depth);
    }
}

scan(div);

Output:

<div> 0
<p> 1
foo
<span> 2
bar
</span> 2
<br /> 2
</p> 1
</div> 0

You could also modify this to output attributes and use the depth argument for indentation.

Reinis I.
Beat me to it. I don't necessarily agree with the article, but everyone should read it.
Rushyo
`innerHTML` is not a method but a property.
Gumbo
Right, thanks. I've been using jQuery's `.html()` for so long that I forget.
Reinis I.
How can i do that. My code in var not in div
faressoft
+4  A: 

You can prettify xml without regex:

var text = "<anything>welcome</anything><anything>Hello</anything>";
var xml = new XML("<root>" + text + "</root>");
console.log(xml.children().toXMLString());

output:

<anything>welcome</anything>
<anything>Hello</anything>

Amarghosh
How to get the output ?
faressoft
@faressoft `var text1 = xml.children().toXMLString();`
Amarghosh
+1 neat approach. E4X has very little availability though.
Anurag
This will only work if it's XHTML right?
Abe Miessler
@Abe Ya, the string should give a valid xml when enclosed in the root tag.
Amarghosh
+1  A: 

Try this:

str.replace(/<(\/?)[a-zA-Z]+(?:[^>"']+|"[^"]*"|'[^']*')*>/g, function($0, $1) {
    return $1 === "/" ? $0+"\n" : "\n"+$0;
})
Gumbo
This code helped me in my project, thanks
faressoft
A: 
text = text.replace(/<(?!\/)/g, "\n<"); // replace every < (which are not followed by /) by \n<
gawi
A: 

Expanding on @Amarghosh's answer:

Assuming the HTML you are trying to parse is more complicated than your example (which I would guess it is) you may want to convert your HTML page into XHTML. This will allow you to use treat it as XML and do a number of things including:

  • Use an XSL to transform the data
  • Use .NET's extensive set of XML libraries to extract and manipulate the data.

I have done this in the past with a free .NET library called SGML.

Abe Miessler