开发者

javascript replace for constructs like {... {..}... }

I want to write a regexp for balanced braces constructs like

{...}, {... {..}...} and {...{..{..}...}..{..}...} where ... means any text, which has no '{' or '}' chars

If I do this:

   txt.replace(/\{[\s\S]+?}/g, function(s){return "_"+s+"_";})

the first } will be considered as end match, so { { } } will become _{ { }_ }

I want a regex to convert this to _{ { } }_

PS: the function(s) part is not from real code, just for example

PPS: I want to do this with regexps if it possible.

PPPS: Highest level of '{' braces included in the text is limited, to 3 or 4 usually

UPDATE: Thanks for comments, Let's l开发者_如何转开发imit the number of nested braces to 3. So:

{ { { .. } .. { .. } } .. { .. } }


Thanks for comments, Let's limit the number of nested braces to 3.

OK, that gives something that we can do with regular expressions. (There are such things as "extended" regular expressions, such as found in Perl or Python, that can match arbitrary nested braces, by using something called "backreferences". I don't know if Javascript's "regular expressions" support those, though.)

We build up the regular expression in pieces.

First, let's figure out what a chunk with no nested braces looks like:

[^{}]*

OK, that was easy. Any number of non-brace characters. :)

A construct with one level of braces, therefore, looks like

{[^{}]*}

since we want braces at the beginning and end, and nowhere else.

How about up to 2 levels?

Well, then we still have braces at beginning and end, and our content can be "any number of chunks of data, each of which has either 0 or 1 levels of braces".

So, we put together "0 or 1 levels of braces" by joining those two expressions with | (so that we match one or the other), and put parentheses around that (because we want to treat that as a whole unit) and a * afterward to denote "any number of this thing we just defined between the parentheses". Then braces go around the whole thing. That gives:

{({[^{}]*}|[^{}]*)*}
  ^^^^^^^^ ^^^^^^
exp. for   exp. for
1 level    0 levels

3 levels of braces are left as an exercise. :) Hint: We apply the same logic - braces enclose any number of chunks, each of which has up to 2 levels of braces.


Regular expressions cannot match balanced text to arbitrary levels of nesting. At least, not without non-regular extensions.

But if the amount of nesting is limited, and you don't mind a fragile and obtuse solution to the problem, then you can make them work.

/{([^{}]*{[^{}]*})*[^{}]*}/

will match against one level of nested braces, and it should be (relatively) straightforward to extend that to the number of levels of nesting you require.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜