关于平衡组的一个例子

我试了一下,貌似没有问题。当然也很可能有问题,因为正则表达式我也是刚入门。
这个表达式是这样的:
^
[^<>]*
((?'open'<[^<>]*)+
(?'close-open'[^<>]*>)+)+
(?(open)(?!))$
作用是判定一个字符串中的尖括号是否配对,如果都配对则返回整个串,否则不返回任何匹配。
首先写下这个东西:
^
Expr
$
表示进行整串匹配,也就是要判断整个字符串是否符合Expr表示的模式。
哦,使用这个正则表达式的时候记得开启忽略空白字符。
如果正则表达式支持宏多好,把<>修改为()时就不用费太多力气了。
Expr::=
    Expr1::=[^<>]*
    Expr2::=(
                      (?'open'<[^<>]*)+
                      (?'close-open'[^<>]*>)+
                 )+
   Expr3::=(?(open)(?!))

[^<>]*不用多说,匹配'<'和'>'之外的任意字符任意多次,这并不是关键。
关键是Expr2。
Expr2中有两个关键构造,(?'Name'Expr)和(?'Name2-Name1'Expr)
第一个我称之为显式命名组,第二个人们称为平衡组。
这是.net framework特有的构造。
显式命名组将捕获到的文本存入名称为Name的堆栈中。所谓捕获到的文本,就是Expr所匹配的文本,(?'Name'Expr)和Expr的区别在于Expr捕获的文本没有存到一个堆栈中,或者说没有存到一个组中。
(?'Name2-Name1'Expr)除了将文本捕获到Name2组中,还pop名为Name的堆栈。
现在我们可以看看Expr2,其意义是“<[^<>]*”至少重复一次,后跟至少一个“[^<>]*>”。具几个匹配这个模式的例子:
<fsd<rew<bvc rewrew>ewr>
然后这整个东西---------->>   (?'open'<[^<>]*)+(?'close-open'[^<>]*>)+  <<----------可以重复多次。
可能说的不是太清楚,我觉得这一步很关键:
<[^<>]* 的实例可以是:<fsdfds、<、<rewrewrew、<fdsfsd dfsfds。
[^<>]*>的实例可以是:fdsfsd>、>、w-ww>。
现在你可以想象出来(<[^<>]*)+ ([^<>]*>)+是什么了。
而 (?'open'<[^<>]*)+(?'close-open'[^<>]*>)+  和它的唯一区别是,(?'open'...每匹配一次,就push该匹配结果到名为open的堆栈,(?'close-open'...每匹配一次,就从open堆栈pop一个元素。open堆栈是<与>是否配对的指示器。
最后Expr3这一部分判断open堆栈是否为空,为空则匹配成功,否则前向断言(?!),这总是导致匹配失败。





转载于:https://www.cnblogs.com/zhy2002/archive/2008/03/04/1090574.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值