1
icerunz OP 是不是换行符一类的匹配出错的原因?
|
2
Livid MOD 用一个循环逐行处理吧。
|
3
manhere 2011-09-08 21:31:26 +08:00
gawk for windows
|
4
bhuztez 2011-09-08 21:36:15 +08:00
regex是可以的吧,
/(BEGIN:VCARD\n((?!END:VCARD)[^\n]*\n)*END:VCARD)/ 临时用 Python 写了下 #!/usr/bin/env python2 import sys, re data = sys.stdin.read() for m in re.findall(r'(BEGIN:VCARD\n((?!END:VCARD)[^\n]*\n)*END:VCARD)', data, re.M): print '**********' print m[0] |
5
bhuztez 2011-09-08 21:37:42 +08:00
print 前面的缩进咋没了,囧
|
7
icerunz OP @bhuztez
这个/(BEGIN:VCARD\n((?!END:VCARD)[^\n]*\n)*END:VCARD)/ 用preg_match_all(); 出来的结果是: array(3) { [0]=> array(0) { } [1]=> array(0) { } [2]=> array(0) { } } |
8
bhuztez 2011-09-08 21:44:09 +08:00
@icerunz 我是用 Python 的那个 re 的,PHP里有多个regex库,不是每个用法和 Python 那个一样的,注意,最前最后的 // 表示的是这里面是一个正则表达式
|
9
icerunz OP 不好意思,我看错一个地方,用
$ereg = "|BEGIN:VCARD([\s\S]+?)END:VCARD|"; 就解决了。 原来写的中间部分是([\s\S]+),后来查了书试着写了个?在里面,成功匹配了。但是还是不大清楚其中的原理……求教…… |
11
Hyperion 2011-09-08 22:13:46 +08:00
@icerunz +一次以上, ?是一次或者零次, 那么就推出...
[a]+? 尽可能少的重复, 至少0次(空位算进去了). "aabaaa" => array("a", "a", "a", "a", "a"); [a]?? 尽可能少的重复, 至少0次(空位算进去了). "aaabaa" => array("", "a", "", "a", "", "a", "", "", "a", "", "a", ""); ??匹配起来太奇怪, 我从来没有用过... |
12
Hyperion 2011-09-08 22:17:24 +08:00
|
13
noahasm 2011-09-08 22:21:38 +08:00
楼主建个临时目录 tmpvcf, 假设大 vcf 文件在其中,名为 all.vcf, 如下命令:
perl -ne 'BEGIN{$/="END:VCARD"} s/^\s+[\r\n]+//; /\w/ && qx/echo "$_" > ${.}.vcf/' all.vcf 应该就 ok 了 |
16
icerunz OP @Hyperion
表5.懒惰限定符 *? 重复任意次,但尽可能少重复 +? 重复1次或更多次,但尽可能少重复 ?? 重复0次或1次,但尽可能少重复 {n,m}? 重复n到m次,但尽可能少重复 {n,}? 重复n次以上,但尽可能少重复 这个资料还是不错的: http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html |
17
noahasm 2011-09-09 12:25:45 +08:00
@icerunz 如下:
perl -ne 'BEGIN{$/="END:VCARD"} s/^\s*[\r\n]+//; /\w/ && qx/echo "$_" > ${.}.vcf/' all.vcf && 就是 and, 左边成立右边才求值(运行) qx// 进行系统调用,和 system 或反引号功能类似, ${.} 其实就是 $., 花括号只是为了和后面 .vcf 的点区分开来 上面的单行命令等效于 perl 程序: #!/usr/bin/env perl my $file = shift; # shift 会取得命令行的第一个参数 $/ = "END:VCARD"; # $/ 指换行符,设为END:VCARD后,perl会以它为每行的结束标记,而不是默认的"\n" open(F, $file) or die $!; while (<F>) { next unless /\w/; # 如果当前行不含a-zA-Z0-9_这些字符,直接跳过 s/^\s*[\r\n]+//; # 删除空白内容 my $line_num = $.; # $. 指当前行号 system "echo \"$_\" > $line_num.vcf"; # system 调用,通过 echo 写入文件 } close F; 把这段 perl 程序寸成 t.pl, 然后运行: perl t.pl all.vcf 效果是一样的. |
18
icerunz OP @noahasm 非常感谢,Perl处理文本真的不是一般NB,再仔细看看。
然后有个疑问,这一句: $/ = "END:VCARD"; # $/ 指换行符,设为END:VCARD后,perl会以它为每行的结束标记,而不是默认的"\n" 中提到的制定END:VCARD为换行符,那是否就表示每一个区块当中在END:VCARD之前的/n都会被忽略掉,而以END:VCARD作为行结尾,整个信息块就被作为一行来处理? .号在Perl里面有特定的含义么? |
19
noahasm 2011-09-09 22:13:17 +08:00
@icerunz 换行符代表一行结束,下起新行,也就是说程序是根据换行符来断行的,在碰到换行符前的所有内容,包括换行符本身算作“一行”内容,和你理解的一样。
. 号在 Perl 里如果不加引号什么的,被称为句点操作符,一般用来连接字符串。 在正则里它是一个元字符,具体可查 http://perldoc.perl.org/perlretut.html $. 是 Perl 的特殊变量,代表当前读入行的行号。 其实这些功能,其他语言也都能做到,比如 python, ruby 等,只不过我用 Perl 最顺手,最熟悉 |
20
icerunz OP @noahasm 谢谢!了解了。开始学习文本处理方面的内容,还有很大差距啊。
你用几种语言?Perl只用作文本方面的处理吧? |
21
args 2011-09-09 23:49:20 +08:00
正则表达是默认是贪婪模式。
|