开发者

Regular Expressions for replacing strings that have one tag type in Javascript

I want to replace all strings between, before and after <span style="[^"]+">.*?</span> tags that may be in string with span tags (no other HTML tags, just simple text) I have regular expression like this.

var span_re = /^(.+)(?=<span)|(?=<\/span>)(.+)(?=<span)|(?=<\/span>)(.+)$/g;
str = str.replace(span_re, '<span>$1</span>');

for this string

'foo<span style="text-decoration:underline;">bar</span>baz'

I got

'<span>foo</span><span style="text-decoration:underline;">bar<span></span>'

I want this:

'<span>foo</span&g开发者_StackOverflowt;<span style="text-decoration:underline;">bar</span><span>baz</span>'

I also try using: .+?, .*? and instead .+ capturing whole expression with no result.

I don't need a parser I don't parse XHTML and don't have self-contained tags.


Parsing HTML using regex is seldom a good idea, particularity in the context of a web browser. Here's a simple example that gets what you want, using jQuery:

Even if that HTML isn't already inside the DOM, it is easy to wrap it in a dummy element:

var wrapper = $('<div />')
wrapper.html('foo<span style="text-decoration:underline;">bar</span>baz');
wrapper.contents()
  .filter(
      function(){return this.nodeType == 3;} //select text nodes only
   ) 
  .wrap('<span />');

As a bonus, that will work well with other tags, and even if you have several <span> tags with free text between them.

Working example: http://jsbin.com/acigu5/


You may be over complicating it. If you know you only may have a single <span>, no other tags and no unescaped > signs, you can use this simple regex:

s = s.replace(/^[^<]+|[^>]+$/gi, '<span>$&</span>');

This regex finds text before the tag (from the beginning, not <) or after the tag (not >, until the end), and wraps them with a <span>. $& in JavaScript regex replace stands for the whole match, or group 0 (on other flavors that may be \0 or $0).

Note that (?=<\/span>) from your original regex is a look-ahead, not a look-behind (JavaScript doesn't have look-behind. shame). That caused (.+) to match the closing tag and consume it, resulting in invalid HTML.

Working example: http://jsbin.com/acexu4/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜