博客地址:blog.csdn.net/cj205
本文所有内容对编译原理有一定基础者没有任何意义!而所谓的单元是我假想的一个()括起来的一个整体单位,你可以理解成运算符的优先级,其实就是这个意思,只是这个概念被弱化了。很多情况下,我们都忽略了一些细节的知识点,今天冷静下来分析一个正则问题的时候,找到了一个小bug(?!<a).*对环视有点基础的一定能看出来这在干什么,也很容易看出来错误在什么地方。(?:(?!<a).)*这说明了一个小的单元概念,即 [元字符或普通字符] 加上 [量词] 组成一个单元。也就是说第一个正则中,这个环视作用范围是 .* 而非 .正则表达式中的范围问题一直都是学习正则和理解(看)正则的一个问题,这对初学者来说必然有所感触。比如,^a|b$这样的正则简单是说被|一次性划开了,因此这个正则的含义是 ^a b$ 而非 ^ a|b $这样的结构。你可以想象成( (^a) | (b$) )这里的小括号是我用来解释的假象单元这样的单元还有如下情况下[abcd]|[abcd][abcd]|[abcd]与([abcd]|[abcd])([abcd]|[abcd])明显就有不同的意思这个很容易理解,为什么呢,因为我用括号括起来了。但是前面2个情况却没有第一个情况是, [元字符或普通字符] 加上 [量词]第二个情况是,整个正则表达式就是一个单元,在这个大的单元里 | 的作用域是所谓“全局作用域”在这里提醒一点,环视的作用范围是下个正则单元,而不是字符单元。即我一开始抛出的问题那么(?!<a>)(<[^>]*>)+的环视作用域在哪呢,或者是正则单元是哪个呢。看下面的例题
string str = "<a><t><t><a><a><a><t><t><t><t><t><a>";
Regex reg = new Regex("(?!<a>)(<[^>]*>)+");
Console.WriteLine(reg.Match(str));output:<t><t><a><a><a><t><t><t><t><t><a>现在你明白了正则单元是什么了对吧。好吧,再加上一条 [正则单元] + 量词 还是一个正则单元我的基础能力我很清楚,所以用编译原理来解释十分吃力,虽然自己能够理顺,但是真的不敢写出来,很期待 过客 续写这么一篇。他的博客和正则看起来都是那么的舒服。绝不拍马溜须,大家都懂的其实本来这东西,简单而且没什么可说的,作为一个及其微不足道的知识点,抛出这个砖来实在有点过意不去,不过这2天同事抱怨正则难读时我连续发现几个由此造成的困难,加上今天晚上这事(别笑我哈),还是记下来比较好。至于发到这里来,一方面是为了散分,最近一段时间打算升星故此可能开始恬不知耻的抢分(不过也没多少时间回帖哈哈哈),另一方面是真的很希望过客更新博客了,到他版块来骚扰下子
本文所有内容对编译原理有一定基础者没有任何意义!而所谓的单元是我假想的一个()括起来的一个整体单位,你可以理解成运算符的优先级,其实就是这个意思,只是这个概念被弱化了。很多情况下,我们都忽略了一些细节的知识点,今天冷静下来分析一个正则问题的时候,找到了一个小bug(?!<a).*对环视有点基础的一定能看出来这在干什么,也很容易看出来错误在什么地方。(?:(?!<a).)*这说明了一个小的单元概念,即 [元字符或普通字符] 加上 [量词] 组成一个单元。也就是说第一个正则中,这个环视作用范围是 .* 而非 .正则表达式中的范围问题一直都是学习正则和理解(看)正则的一个问题,这对初学者来说必然有所感触。比如,^a|b$这样的正则简单是说被|一次性划开了,因此这个正则的含义是 ^a b$ 而非 ^ a|b $这样的结构。你可以想象成( (^a) | (b$) )这里的小括号是我用来解释的假象单元这样的单元还有如下情况下[abcd]|[abcd][abcd]|[abcd]与([abcd]|[abcd])([abcd]|[abcd])明显就有不同的意思这个很容易理解,为什么呢,因为我用括号括起来了。但是前面2个情况却没有第一个情况是, [元字符或普通字符] 加上 [量词]第二个情况是,整个正则表达式就是一个单元,在这个大的单元里 | 的作用域是所谓“全局作用域”在这里提醒一点,环视的作用范围是下个正则单元,而不是字符单元。即我一开始抛出的问题那么(?!<a>)(<[^>]*>)+的环视作用域在哪呢,或者是正则单元是哪个呢。看下面的例题
string str = "<a><t><t><a><a><a><t><t><t><t><t><a>";
Regex reg = new Regex("(?!<a>)(<[^>]*>)+");
Console.WriteLine(reg.Match(str));output:<t><t><a><a><a><t><t><t><t><t><a>现在你明白了正则单元是什么了对吧。好吧,再加上一条 [正则单元] + 量词 还是一个正则单元我的基础能力我很清楚,所以用编译原理来解释十分吃力,虽然自己能够理顺,但是真的不敢写出来,很期待 过客 续写这么一篇。他的博客和正则看起来都是那么的舒服。绝不拍马溜须,大家都懂的其实本来这东西,简单而且没什么可说的,作为一个及其微不足道的知识点,抛出这个砖来实在有点过意不去,不过这2天同事抱怨正则难读时我连续发现几个由此造成的困难,加上今天晚上这事(别笑我哈),还是记下来比较好。至于发到这里来,一方面是为了散分,最近一段时间打算升星故此可能开始恬不知耻的抢分(不过也没多少时间回帖哈哈哈),另一方面是真的很希望过客更新博客了,到他版块来骚扰下子
string str = "<a><t><t><a><a><a><t><t><t><t><t><a>";
Regex reg = new Regex("(?!<a>)(<[^>]*>)+");
Console.WriteLine(reg.Match(str).Value);ps:同是没怎么看懂此帖
但是我觉得此帖不应该淹没在如此多的无意义的回复之中
应该考虑元子组:功能,阻止回溯。
(?>)非命名捕获分组:压栈使用,match/split分开描述
()命名捕获分组:压栈使用,同上,但有区别
(?<name>)取消分组的单元
(?:)(?n)模式分组的目的是在回溯的时候,分组后表达式失配时,回溯点不是前一个标记,而是从整个分组前方重来。如果分组内回溯可能较多,分组后面稍微有个几十次的回溯,这个表达式的回溯就几何数量上涨了。可惜我们的.net 正则引擎是那么的诚实,就给你来一个超大循环,卡住程序了。^_^ 我也抛砖。等客客。
string str = "abcdefg";
Regex reg1 = new Regex("(?=(?<key>.)).*");
Regex reg2 = new Regex("((?=(?<key>.)).)*");
Match m1 = reg1.Match(str);
foreach (var i in m1.Groups["key"].Captures)
{
Console.WriteLine(i);
/*
output:
* a
*/
} Match m2 = reg2.Match(str);
foreach (var i in m2.Groups["key"].Captures)
{
Console.WriteLine(i);
/*
output:
* a
* b
* c
* d
* e
* f
* g
*/
}
正则在匹配的过程中是的捕获的还是不捕获的,必要的回溯该有他还是有,必要的环视该出现还是出现。
其实我不是想说环视,环视只是其中一种情况体现。
说白了,就是想说"运算符"的优先级.*比较近(?!a).*中环视相对量词比较远^ab|cd$ 中
ab和cd远于 ^和ab。
如果我们做四则运算有{[(
但是有了优先级*/高于+-
于是乎
a*b-c*d就不需要括号了
在正则中,似乎没有多少资料单独的提及或者强调优先级。
我想抛出问题来,等过客来琢玉。结果他还是那么忙。要不逍遥你来。
过客60楼回复也很精彩
(?!a).+
等价于
(?!a)..*
也就是它所作用的位置就是第一个小数点前的位置,而不是第二个小数点前的位置
平时还真没注意
64楼的例子很精彩,第二个正则比较好理解,但是第一个为什么只能匹配到字符a呢?
string str = "abcdefg";
Regex reg1 = new Regex("(?=(?<key>.)).*");
有点儿晕了
(
(?=(?<key>.))
.)
将匹配N次而第一个里面*只是作用于最后一个.
而对于(?=(?<key>.))这个位置只匹配一次,所以key组当然也是一次若不对请指正,呵呵
推荐使用这个软件书写测试正则公式