免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
论坛 程序设计 Perl 除法题
最近访问板块 发新帖
楼主: leigh111
打印 上一主题 下一主题

除法题 [复制链接]

论坛徽章:
0
31 [报告]
发表于 2009-09-29 10:03 |只看该作者
楼主中文没学好,感觉表达能力还不如小学生

论坛徽章:
0
32 [报告]
发表于 2009-09-29 10:15 |只看该作者
原帖由 toniz 于 2009-9-29 09:11 发表



我发的代码肯定是可以跑的。你是哪个地方跑不过了?
其实正则表达式那里,用/r/n或者/r或者/n,具体要看你保存文本的格式是 DOS还是mac还是unix。这个其实只是换行符的问题。


今天没上班,在家又试验了一把,发现代码竟然跑过了,仔细回忆了下,知道问题出在什么地方了:当时我的数据,是自己随手敲的,内容和lz贴的基本相同,但是每段数据后,我多敲了一个换行符,也就是每段数据和 title 之间有一个空行。
于是我本地多加了一个换行,结果都匹配不上了……这个,我仔细看了下,([\d\D]*?)(?=NTSEQ)为啥对于data后面多了一个换行符后,就匹配不上,没想明白?

当然,我之前说的,也确实有问题,regex是没问题的,而是我对 '/g'  理解狭隘了,没有想到对包含换行符的字符串,也是可以全局匹配的,我以为只匹配第一行了……
至于换行符,这个我倒是注意了,不过换成 '\n' 是不是更好,反正 '\r\n' 也是会匹配 '\n' 的。

论坛徽章:
0
33 [报告]
发表于 2009-09-29 10:24 |只看该作者

回复 #32 dugu072 的帖子

这个是换行符的问题。不同系统的换行符号是不一样的。
如果你想把换行符的因素考虑进去,那么可以用下面的正则去匹配:
my %rf= ($file_contend  =~ /(NTSEQ.*?)(?:\r\n|\r|\n)([\d\D]*?)(?=NTSEQ)/g);

论坛徽章:
0
34 [报告]
发表于 2009-09-29 10:31 |只看该作者
不应该是换行符,我都有看过,我新加的换行符,是 '\r\n',之前的换行符也是 '\r\n'

另外,我是在前一段 data 和另一段 title 之间加了一个换行,此时,能regex 上应该匹配的是 ([\d\D]*?)(?=NTSEQ),此时 [\d\D]应该不会考虑换行符的问题。

论坛徽章:
0
35 [报告]
发表于 2009-09-29 11:03 |只看该作者

回复 #34 dugu072 的帖子

恩  你应该只是接触过windows系统吧。不然不会在这个问题上纠缠这么久。

*?是非贪婪,只要遇到第一个合适的就算完了。[\d\D]是两个互补的东西,可以匹配任意字符。
也就是说HASH的KEY取到以(NTSEQ.*?)(?:\r\n|\r|\n)开头的一行完了。
HASH的value取到遇到的第二个NTSEQ之前。

论坛徽章:
0
36 [报告]
发表于 2009-09-29 12:28 |只看该作者
原帖由 toniz 于 2009-9-29 11:03 发表
恩  你应该只是接触过windows系统吧。不然不会在这个问题上纠缠这么久。

*?是非贪婪,只要遇到第一个合适的就算完了。[\d\D]是两个互补的东西,可以匹配任意字符。
也就是说HASH的KEY取到以(NTSEQ.*?)(?:\ ...


不知道你是如何看出我只是接触了windows的……

我已经清楚说过了 [\d\D]是无关换行符的,不知道你为什么没有看见. 至于说语法问题,我想,我还是看得明白的,还不至于在这里长篇讨论基本的语法问题!
只想问下,你有试过我说的问题吗?实践出真知,有不少东西,我们自以为很明白,但也许就是一些细节,容易被忽略,我这里和你讨论这个 regex 问题,只是想找出,可能被忽略的原因而已

论坛徽章:
0
37 [报告]
发表于 2009-09-29 13:51 |只看该作者
原帖由 dugu072 于 2009-9-29 12:28 发表


不知道你是如何看出我只是接触了windows的……

我已经清楚说过了 [\d\D]是无关换行符的,不知道你为什么没有看见. 至于说语法问题,我想,我还是看得明白的,还不至于在这里长篇讨论基本的语法问题!
只 ...



那就真不知道你想表达什么了。
把你的测试数据贴出来吧。毕竟像这种精确匹配的正则表达式还是要看具体数据的。

论坛徽章:
0
38 [报告]
发表于 2009-09-29 15:04 |只看该作者
原帖由 toniz 于 2009-9-29 13:51 发表



那就真不知道你想表达什么了。
把你的测试数据贴出来吧。毕竟像这种精确匹配的正则表达式还是要看具体数据的。


不用发数据了,我把你的代码的数据的hex值都打出来跟了一遍,发现了确实存在一些问题,也是为什么我跑不过的原因:
逻辑问题:
    my %rf= ($file_contend  =~ /(NTSEQ.*?\r\n)([\d\D]*?)(?=NTSEQ)/g);
    这里由于是全局匹配所有字符,且包括换行,因此对于 data 的 length 计算,你会将 换行符 统计进去,因此,我在数据后加上一个回车后,自然导致length增加,而无法显示
语法问题:
    上述你认为的 windows 中的换行符 \r\n ,是不应该如此使用的,因为Windows下 Perl 缺省打开的文件句柄是 text mode,对于 <> 等读操作,会自动将 '\r\n' 转换为 '\n' ,因此,在你的代码中,将永远看不到 \r\n 的数据,除非 binmode( FH ) 一下,当然更简单的,Perl 就是想让换行符平台无关,直接 '\n' 替代即可

所以,如果诸如如下数据:
NTSEQ       339
            a #注意只有一个 数据 'a'
NTSEQ       276
反而是可以匹配的,因为后面如果加上 '\r\n' 就刚好是 3个字符(前提是你用了 binmode)。

论坛徽章:
0
39 [报告]
发表于 2009-09-29 15:30 |只看该作者

回复 #38 dugu072 的帖子

真晕呢
说来说去,是你自己加个换行,然后说出了问题。
写正则就要先看数据的规律,你加了个换行,数据的规律就不一样了。
你非要加个换行,那就把(?:\r\n|\r|\n)后面加个+号或者是{1,X}.
具体看你的数据是怎么增加的。

论坛徽章:
0
40 [报告]
发表于 2009-09-29 15:38 |只看该作者

回复 #38 dugu072 的帖子

而且像你这样说的这样有N个换行之类的话,或者是你还想字母中间还会出现空格这类的话,
那么最好是在EACH循环里对$VALUE值在处理一下了。不然正则会看起来很繁琐。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP