ccccccc

tylyj 2011-04-19 11:43:39
博客地址: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天同事抱怨正则难读时我连续发现几个由此造成的困难,加上今天晚上这事(别笑我哈),还是记下来比较好。至于发到这里来,一方面是为了散分,最近一段时间打算升星故此可能开始恬不知耻的抢分(不过也没多少时间回帖哈哈哈),另一方面是真的很希望过客更新博客了,到他版块来骚扰下子
...全文
78 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
朕赐你肥皂 2011-04-20
  • 打赏
  • 举报
回复
别紧张,慢慢说
lanqiang456 2011-04-20
  • 打赏
  • 举报
回复
虽然不知道楼主在说什么但是还是觉得楼主很牛逼
  • 打赏
  • 举报
回复
嗯 结贴
东莞寻香苑 2011-04-20
  • 打赏
  • 举报
回复
呵呵,这样
swalp 2011-04-20
  • 打赏
  • 举报
回复
结了吧。
Description Mountain Watching [Jeffrey Wang, 2009] One day, Bessie was gazing off into the distance at the beautiful Wisconsin mountains when she wondered to herself: which mountain is the widest one? She decided to take N (1 <= N <= 100,000) equally-spaced height measurements H_i (1 <= H_i <= 1,000,000,000) sequentially along the horizon using her new Acme Long Distance Geoaltimeter. A mountain is defined to be a consecutive sequence of H_i values which increases (or stays the same) and then decreases (or stays the same), e.g., 2, 3, 3, 5, 4, 4, 1. It is possible for a mountain on the edge of her field of vision only to increase or only to decrease in height, as well. The width of a mountain is the number of measurements it encompasses. Help Bessie identify the widest mountain. Here's a simple example of a typical horizon: ******* * ********* *** ********** ***** *********** ********* * * ***************** *********** *** * ** ******************* ************* * * ******* * ********************************************************************** 3211112333677777776543332111112344456765432111212111112343232111111211 aaaaaa ccccccccccccccccccccc eeeeeee ggggggggg bbbbbbbbbbbbbbbbbbbbbbbbbbbb ddddd ffffffffff hhhhhhhhh The mountains are marked 'a', 'b', etc. Obviously, mountain b is widest with width 28. The mountain on the left has width 6 for the purposes of this task. Input * There are multiple test cases. * For each case: ** Line 1: A single integer: N ** Lines 2..N+1: Line i+1 contains a single integer: H_i Output * For each case: ** Line 1: A single line with a single integer that is the width of the widest mountain. Sample Input 7 3 2 3 5 4 1 6 INPUT DETAILS: The height measurements are 3, 2, 3, 5, 4, 1, 6. Sample Output 5 OUTPUT DETAILS: The widest mountain consists of the measurements 2, 3, 5, 4, 1. Other mountains include 3, 2 and 1, 6
对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<、<=、!=),并非说用>,>=,=,between..and 时会提示SQL语法错误,而是经常是查不出一条记录来,还会出现似乎是莫名其妙的结果来,其实您只要理解好了这个 rownum 伪列的意义就不应该感到惊奇,同样是伪列,rownum 与 rowid 可有些不一样,下面以例子说明 假设某个表 t1(c1) 有 20 条记录 如果用 select rownum,c1 from t1 where rownum < 10, 只要是用小于号,查出来的结果很容易地与一般理解在概念上能达成一致,应该不会有任何疑问的。 可如果用 select rownum,c1 from t1 where rownum > 10 (如果写下这样的查询语句,这时候在您的头脑中应该是想得到表中后面10条记录),你就会发现,显示出来的结果要让您失望了,也许您还会怀疑是不谁删了一些记录,然后查看记录数,仍然是 20 条啊?那问题是出在哪呢? 先好好理解 rownum 的意义吧。因为ROWNUM是对结果集加的一个伪列,即先查到结果集之后再加上去的一个列 (强调:先要有结果集)。简单的说 rownum 是对符合条件结果的序列号。它总是从1开始排起的。所以你选出的结果不可能没有1,而有其他大于1的值。所以您没办法期望得到下面的结果集: 11 aaaaaaaa 12 bbbbbbb 13 ccccccc ................. rownum >10 没有记录,因为第一条不满足去掉的话,第二条的ROWNUM又成了1,所以永远没有满足条件的记录。或者可以这样理解: ROWNUM是一个序列,是oracle数据库从数据文件或缓冲区中读取数据的顺序。它取得第一条记录则rownum值为1,第二条为2,依次类推。如果你用>,>=,=,between...and这些条件,因为从缓冲区或数据文件中得到的第一条记录的rownum为1,则被删除,接着取下条,可是它的rownum还是1,又被删除,依次类推,便没有了数据。 有了以上从不同方面建立起来的对 rownum 的概念,那我们可以来认识使用 rownum 的几种现像 1. select rownum,c1 from t1 where rownum != 10 为何是返回前9条数据呢?它与 select rownum,c1 from tablename where rownum < 10 返回的结果集是一样的呢? 因为是在查询到结果集后,显示完第 9 条记录后,之后的记录也都是 != 10,或者 >=10,所以只显示前面9条记录。也可以这样理解,rownum 为9后的记录的 rownum为10,因条件为 !=10,所以去掉,其后记录补上,rownum又是10,也去掉,如果下去也就只会显示前面9条记录了 2. 为什么 rownum >1 时查不到一条记录,而 rownum >0 或 rownum >=1 却总显示所以的记录 因为 rownum 是在查询到的结果集后加上去的,它总是从1开始 3. 为什么 between 1 and 10 或者 between 0 and 10 能查到结果,而用 between 2 and 10 却得不到结果 原因同上一样,因为 rownum 总是从 1 开始 从上可以看出,任何时候想把 rownum = 1 这条记录抛弃是不对的,它在结果集中是不可或缺的,少了rownum=1 就像空中楼阁一般不能存在,所以你的 rownum 条件要包含到 1 但如果就是想要用 rownum > 10 这种条件的话话就要用嵌套语句,把 rownum 先生成,然后对他进行查询。 select * from (selet rownum as rn,t1.* from a where ...) where rn >10 一般代码中对结果集进行分页就是这么干的。 另外:rowid 与 rownum 虽都被称为伪列,但它们的存在方式是不一样的,rowid 可以说是物理存在的,表示记录在表空间中的唯一位置ID,在DB中唯一。只要记录没被搬动过,rowid是不变的。rowid 相对于表来说又像表中的一般列,所以以 rowid 为条件就不会有 rownum那些情况发生。 另外还要注意:rownum不能以任何基表的名称作为前缀。

7,765

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧