菜鸟继续求解
有一个简单的非格式化文本文件需要对它进行格式化。非格式化的文本文件形式如下:
{"alias", "Display, add, delete alias string\r\n# alias\r\n# alias <alias name>\r\n# alias <alias name> <replaced text>\r"},
{"create", "Create ds0 bundles\r\n# create ds0bundle <NN> \r\n -startds0 <NN>\r\n -endds0 <NN> \r\n [-cic <string>] \r\n"},
格式化后的文本形式如下:
{"alias", "Display, add, delete alias string\r\n" \
"# alias\r\n" \
"# alias <alias name>\r\n" \
"# alias <alias name> <replaced text>\r"},
{"create", "Create ds0 bundles\r\n" \
"# create ds0bundle <NN> \r\n" \
" -startds0 <NN>\r\n" \
" -endds0 <NN> \r\n" \
" [-cic <string>] \r\n"},
请求大牛们给出一个参考程序。
问题点数:100、回复次数:12Top
1 楼numchun(chunchun)回复于 2006-03-14 17:23:32 得分 0
上面的帖子提交后没有格式化了。这里简单的把格式描述一下:
字符串分割后接下来的字符串行应该和前面的字符串对其。例如,第一个格式化后的例子中,第二、三、四行的"#alias 应该和第一行的"Display 对齐。Top
2 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-14 17:28:36 得分 20
while(<>){
s/(\\r\\n)/$1\" \\ \n\"/g;
print ;
}
不对齐的是这样
使用方法 perl test.pl result.txt > result_out.txt
Top
3 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-14 17:37:07 得分 20
while(<>){
$ident = $1 if /(([^\"]*\"){2}[^\"]*)/;
$ident =~ s/./ /g;
s/(\\r\\n)/$1\" \\ \n$ident\"/g;
print ;
}
对齐的是这样Top
4 楼numchun(chunchun)回复于 2006-03-14 17:39:56 得分 0
谢谢。
如果对齐,则需要如何修改?
另外:
如何把这段程序放在和你上次给我的程序里?Top
5 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-14 17:42:43 得分 20
while(<>){
$ident = $1 if /(([^\"]*\"){2}[^\"]*)/;
$ident =~ s/./ /g;
s/(\\r\\n)([^\"])/$1\" \\ \n$ident\"$2/g;
print ;
}
稍微修改一下Top
6 楼numchun(chunchun)回复于 2006-03-14 18:00:01 得分 0
空格太多了,没有对齐。
呵呵,我实在看不懂你的程序。我还没有入门呢,所以也没法修改这段程序,所以还得请大牛帮我搞定。
不过我把这段程序简单的修改后,在根据我的一些其他的需求,集成在你上次给我的程序中,倒是能工作了。集成后的程序如下:
$/ = ">";
open(RESULT, ">result.txt");
while(<>){
s/helphandler=""/helphandler="help_handler_function"/g if /<command/ or /<pd/;
s/helpmethod="0"/helpmethod="1"/g if /<command/ or /<pd/;
my ($kw, $hp);
if(/(keyword=")([^\"]*)"/){
$kw = $2;
}
if(/(help=")([^\"]*)"/){
$_ = "(".$`.$1."\"".$'.")";
$hp = $2;
}
elsif(/(helpstr=")([^\"]*)"/){
$_ = "(".$`.$1."\"".$'.")";
$hp = $2;
}
$hp =~ s/>/>/g;
$hp =~ s/</</g;
$ident = $1 if /(([^\"]*\"){2}[^\"]*)/;
$ident =~ s/./ /g;
$_ = $hp;
s/(\\r\\n)([^\"])/$1\" \\ \n$ident\"$2/g;
$hp = $_;
$kw =~ s/>/>/g;
$kw =~ s/</</g;
$kw =~ s/@@/./g;
print RESULT " {\"".$kw."\", \"".$hp. "\"},\n" if $kw or $hp;
print ;
}
close(RESULT);
呵呵,请你看看是否合乎逻辑。Top
7 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-14 18:03:53 得分 10
没有必要和在一起,把上次的result.txt读入新程序就可以了
Top
8 楼numchun(chunchun)回复于 2006-03-15 09:36:56 得分 0
呵呵,提一个非份要求。
能不能把这段程序
while(<>){
$ident = $1 if /(([^\"]*\"){2}[^\"]*)/;
$ident =~ s/./ /g;
s/(\\r\\n)([^\"])/$1\" \\ \n$ident\"$2/g;
print ;
}
给我写一些注释啊?
俺还没有足够的功力看懂这个程序。Top
9 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-15 12:46:05 得分 30
while(<>){
}
的结构能够遍历处理输入文件的每一行,累加器变量$_作为行的内容
以一行
$_ = {"alias", "Display, add, delete alias string\r\n# alias\r\n# alias <alias name>\r\n# alias <alias name> <replaced text>\r"}
为例
$ident = $1 if /(([^\"]*\"){2}[^\"]*)/; # 这样也许更好些 $ident = $& if /^([^\"]*\"){2}[^\"]*/;
匹配第三个 双引号 " 也就是Display的要求,这样得到$ident = '{"alias", '; 这个长度恰好是需要缩进的距离。
$ident =~ s/./ /g;
则是把$indent变量替换成同长度的空白字符串。因为有缩进的要求,这时候 $ident = ' ';
然后对$_ 进行分行处理
s/(\\r\\n)([^\"])/$1\" \\ \n$ident\"$2/g;
实际就是把 除了最后一行外的所有的"\\r\\n"后面插入 " \\"."\n".$ident."\"", 就变成你所需要的了。记住$ident这里是一系列的空白符号.
Top
10 楼numchun(chunchun)回复于 2006-03-15 16:56:24 得分 0
嗯,有点明白了。只是对正则表达式中一些匹配的符号不是很熟悉。我第一次接触perl,也就昨天和今天看了一点资料,呵呵。打算以此为契机,好好学习perl。
由于我们的这个文本文件的格式有点乱,现在经过你给我的程序处理后还是有一些格式不符合我们的要求。具体表现:
1. 有些\r和\n之间有一系列的空格,具体空格个数不定。如何才能把这些空格去掉?
2. 有些\r\n之后会有一系列空格,具体空格数量亦不祥,需要把这些空格去掉。
请问如何处理?
昨天的第一个程序请参考7楼。
另外,我想对结果进行进一步的处理。需求如下:
1. 示例文本如下(其格式是{"keyword","helpstring"})
{"dscp", ""},
{"-eq", "<0-63>"},
{"-mask", "<6 bits>"},
{"ethertype", ""},
{"-eq", "<0-65535>"},
{"-mask", "<16 blits>"},
{"ip", ""},
{"-sel", ""},
{"-eq", ""},
{"-mask", ""},
{"iptype", ""},
{"-eq", "<0-255>"},
{"-mask", "<8 blits>"},
{"l4port", ""},
{"-sel", ""},
{"-eq", "<0-65535>"},
{"-mask", "<16 bits>"},
2. 由于历史原因,上述文本中keyword有些是重复的。现在需要把重复的{"keyword","helpstring"}对抽取出来,放在另外一个文件中。
能否给个解答?
谢谢
Top
11 楼numchun(chunchun)回复于 2006-03-22 17:37:19 得分 0
感谢xyzxyz1111的帮助。结帖谢过!Top
12 楼xyzxyz1111(程序员的自我修养)回复于 2006-03-22 20:49:27 得分 0
哪里可能有空格,哪里就加上\s*
重复的可以用hash表来处理
Top




