设为首页 收藏本站
查看: 928|回复: 0

[经验分享] perl处理文本经验积累(不断更新中)

[复制链接]

尚未签到

发表于 2017-5-19 11:30:01 | 显示全部楼层 |阅读模式
  1. 把同根路径不同文件包中同名的文件合并
  例子:
  作用描述: 问题:
现有五个目录分别存放5个领域的文件
F:\...\fold\canyin\sys
F:\...\fold\jiaotong\sys
F:\...\fold\lvyou\sys
F:\...\fold\shangwu\sys
F:\...\fold\tiyu\sys

而每个
F:\...\fold\xxx\sys目录
下面有
18个文件:
text(0).txt
text(1).txt
....
text(16).txt
text(17).txt

想把五个领域目录下的文件名相同的文件合并成一个文件

比如:
all_text(0).txt=
(F:\...\fold\canyin\sys\text(0).txt)
+(F:\...\fold\jiaotong\sys\text(0).txt)
+(F:\...\fold\lvyou\sys\text(0).txt)
+(F:\...\fold\shangwu\sys\text(0).txt)
+(F:\...\fold\tiyu\sys\text(0).txt)
这里的'+'表示文件合并的意思
即后面处于不同目录下面的五个同名文件将被合并到all_text(0).txt文件中

  #!
@person=qw(canyin jiaotong lvyou shangwu tiyu);
for($i=0;$i<18;$i++) {
$src=join('+',map{$_."\\sys\\test_part_result_by_index($i).txt"} @person);
print $src ,"\n";
system("copy $src fold1_all_text($i).txt");
}
  2. 简易获取当前目录下所有文件名
  一般是用CWD模块,下面这个更简洁
  #!
#####
#给目录下面的文件改名字
while($file=glob('*.txt')) {#glob 取得当前目录下的文件名
print "$file\n";
$newfile = "canyin_".$file;
rename($file,$newfile);
print "$newfile\n";
}
  3. 去除文件每行前标号
  在EBMT翻译时,为防止串行一般在每行前加标号,格式如:[0001234]
  在评测前,需要去掉之,代码如下: 写成批处理即可运行。
  #!
$inputfile =shift ;
$outputfile = shift;
open IN,"<$inputfile" or die "can not open file : $inputfile\n";
open OUT,">$outputfile" or die "can not open file : $outputfile\n";
foreach $str (<IN>){

$str =~s/^\[( \d+ )\]//g;#去掉行首[ 12121212 ]
$str =~s/^ //g;#去掉行首空格
print OUT $str;
}
  4. 从评测结果文件中提取结果:
  #!
  $inputfile = shift;
  $outputfile = shift;
open IN ,$inputfile or die "can not open file,$!\n ";
open OUT, ">$outputfile" or die"can not open >out.txt,$!\n";
  my $contents = <IN>;
my @system_names;
$sys = "system name= \"";
$nist5 = "Nist5Score=\"";
$bleu5 = "Bleu5Score=\"";
my @nist5score;
my @nist3score;
my @nist1score;
my @bleu5score;
my @bleu3score;
my @bleu3score;
#@system_names = /$sys(.*?)\"/g;
$sys ="<system name=\"";
  @system_names=($contents=~/$sys(.*?)\"/gs);
@nist5score = ($contents=~/$nist5(.*?)\"/gs);
@bleu5score = ($contents=~/$bleu5(.*?)\"/gs);
print OUT join("\n",@system_names);
print OUT "\nnist5\n";
print OUT join("\n",@nist5score);
print OUT "\nbleu5\n";
print OUT join("\n",@bleu5score);
5。把文件随机化
  #!/usr/bin/perl
#功能: 把输入文件随机化(每行是一个单位)
#方法:每次产生一个在总行数之间的随机整数,用一个标记数组看有是否已经输出。
  use strict;
my $n = 100;
my $seed = 1;
#Do not call srand() (i.e. without an argument) more than once in
#a script. The internal state of the random number generator
#should contain more entropy than can be provided by any seed, so
#calling srand() again actually *loses* randomness.
  my $infile = shift;
my $outfile = shift;
open(IN,$infile) || die "无法打开input.txt\n";
open (OUT,">$outfile")|| die "无法打开output.txt\n";
  my @all = <IN>;
my $sen_num = @all;#总句子数
my $cur_num = 0;#目前提取的句数
my @lab ;#标记数组
my $selected = 100;
my $non_selected = 0;
  srand();
  #先把标记数组初始化
my $i=0;
for($i=0;$i<@all;$i++)
{
$lab[$i] = $non_selected;
}
  my $num = 0;
while($cur_num < $sen_num)
{
$num = int rand($sen_num);

if($lab[$num] != $selected)
{
print OUT @all[$num];

$lab[$num] = $selected;
$cur_num ++;
#$num ++;
}
}
  6. 上面的随机做法效率很低,建议用下面这个很棒的shuffle做法。
  #!
use List::Util 'shuffle';
@all = <STDIN>;
$num = @all;
@list = (0..$num-1);
@shuffled = shuffle(@list);
foreach $i(@shuffled){
print $all[$i];
}
  

7. 文件成行读入
把一个文件读入一个字符串
方法:
my $contents;
{
local $/;
$contents = <IN>;
}

my $contents = do {local $/; <IN>}
例子: 文件中以空行为语块分割的标记,把语块内部顺序保留,而语块间逆序输出。
#!
open IN,"input.txt";
open OUT,">output.txt";
my $contents;
{
local $/;
$contents = <IN>;
}
my @all = split("\n\n",$contents);#不同文件格式也可能是my @all = split("\n\r\n",$contents);
for(my $i=@all-1;$i>=0;$i--)
{
print OUT $all[$i],"\n\n";
}
close(IN);
close(OUT);
  8. 如何用foreach每次读取多句?
那就用<FH>读三次,
while (!eof(FH)){
$line1 = <FH>;
$line2 = <FH>;
$line3 = <FH>;
...
}
  
9 (非)贪婪(non-greedy)匹配
  ? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,
匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,
而默认的贪婪模式则尽可能多的匹配所搜索的字符串。
例如,对于字符串 "oooo",’o+?’ 将匹配单个"o",而 ’o+’ 将匹配所有 ’o’。
  如果你使用一个旧的Perl版本, 并且你不想贪婪匹配, 你必须使用否定的字符类。(真的, 你正在得到一种限制的贪婪匹配)
  在Perl的现在版本中, 你能通过在数量词后使用一个问号,
强迫进行非贪婪的最小匹配。 
同样的用户名匹配将是/.*?:/。现在这个.*?将尽可能匹配少的字符, 而不是尽可能多的字符,
所以它停在第一个冒号而不是最后一个冒号。
  例子:
问题是这样的:
比如给一句话,形式如下:
I(i)/xx came(come)/xx ,(,)/xx ((()/xx {({)/xx how it like(how it like)/yy
解释格式:
词组,然后是用小括号包围的词组还原形式,然后是斜杠'/',然后是词性..
  要求: 把还原形式去掉
例如上句想得到:
I/xx came/xx ,/xx (/xx {/xx how it like/yy
  难点: 1. 词组可能是左小括号'(' 即可能有词组: ((()/xx
2. 各种标点,括号() [] {}等
3. 好几个词的词组,如: How it like(how it like)/xx
  做法: 拆分成一段一段来做吧,要不然用regexp处理各段之间的混淆很麻烦:
  my $str="I(i)/xx came(come)/xx ,(,)/xx ((()/xx )())/x {({)/xx how it like(how it like)/yy";
my $res='';
while($str=~m|(.*?/\S+)|g) {# 非贪婪匹配,否则结果就是 I/yy
my $token=$1;
$token=~s|\(\(\(\)|\(|g;
$token=~s|\)\(\)\)|\)|g;
$token=~s|\(.*\)||g;
$res.=$token;
}
print $res,"\n";

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-379063-1-1.html 上篇帖子: perl-opengl基本图形操作-缩放,二维旋转,二维平移 下篇帖子: Perl中常用到的一些模板代码(BASIC)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表