免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2195 | 回复: 4
打印 上一主题 下一主题

怎样可以对一大段文字中的若干小段(可能包含其他小段)加以正则替换??? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-01-06 20:44 |只看该作者 |倒序浏览
本帖最后由 死水站 于 2015-01-06 20:50 编辑

问题在最后,代码只是随便示例一下

具体问题是这样,有一大段文字,差不多是这个意思:

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……
***

想修改“三”下面的1,2,3部分

想了一下,一种是把整个文字放在一个$foo里面,然后匹配出各段“三”,用flag替换;匹配出来的段落更改之后再换回去。($&大不出来,就“$与”了,呵呵)
  1. while (foo =~ s/(?<=\n)三[^一二]+?/flag/){
  2.         my $temp = $与;
  3.         $temp =~ s///g;#处理1,2,3部分
  4.         foo =~ s/flag/$temp/;
  5. }
复制代码
当然,这个在while里面改$foo的事情还没来级实验,但是大概是这个思路

另一种方法,就是用@foos放置这段文字,每行占一个元素单元,找出“三”这些段落的头尾,做更改
  1. my $i = 0;
  2. my @times;
  3. my $j = 0; #数组计数
  4. while(defined($foos[$i])){
  5.         if($foos[$i] eq "三"){
  6.                 $times[$j] = $i;
  7.                 $j++;
  8.                 while($foos[$i] ne "一"){
  9.                         $i++;
  10.                 }
  11.                 $times[$j] = $i-1;
  12.                 $j++;
  13.         }
  14.         $i++;
  15. }
复制代码
差不多这个意思,@times里面就存了“三”这些段落的首尾,然后就可以根据这些$foos[$tmies[$k]] =~ s///;来处理了
-------------------------------

问题是,这样好复杂啊,调来调去的。有没有什么方法,可以实时追踪比如s///;的位置并加以控制??这样我可以直接$foos =~ s///;了


论坛徽章:
0
2 [报告]
发表于 2015-01-06 23:51 |只看该作者
实时追踪?是要用seek和tell吗?
  1. use strict;
  2. use Fcntl ':seek';
  3. open my $file, "< try.txt";
  4. seek $file, 0 , SEEK_SET;
  5. my $position;
  6. while (<$file>) {
  7. print $_;
  8.     if (/三/) {
  9.         while (<$file>) {
  10.             if (/balbala/) {
  11.                 $_ =~ s/balbala/xxxxxxx/g;
  12.                 print $_;
  13.                 next;
  14.             } else {
  15.                 print $_;
  16.                 $position = tell $file;
  17.                 seek $file, $position, SEEK_SET;
  18.                 last;
  19.             }
  20.         }
  21.     }
  22. }
复制代码
output:

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1xxxxxxx……
   2xxxxxxx……
   3xxxxxxx……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1xxxxxxx……
   2xxxxxxx……
   3xxxxxxx……

   1balbala……
   2balbala……
   3balbala……

   1balbala……
   2balbala……
   3balbala……

   1xxxxxxx……
   2xxxxxxx……
   3xxxxxxx……

论坛徽章:
0
3 [报告]
发表于 2015-01-07 09:06 |只看该作者
本帖最后由 死水站 于 2015-01-07 09:07 编辑

果然藏龙卧虎,哈哈,谢谢啦~

有两点疑问,

一个是常量 SEEK_SET貌似初值没赋?

另一个逻辑上的,第六和第九行,
  1. use strict;
  2. use Fcntl ':seek';
  3. open my $file, "< try.txt";
  4. seek $file, 0 , SEEK_SET;
  5. my $position;
  6. while (<$file>) {
  7. print $_;
  8.     if (/三/) {
  9.         while (<$file>) {
复制代码
都是while(<$file>),都是从头读$file吗?
还是说第九行的是从遇到“三”之后?那这个位置怎么记录下来的?


回复 2# b4and5


   

论坛徽章:
0
4 [报告]
发表于 2015-01-07 09:34 |只看该作者
本帖最后由 b4and5 于 2015-01-07 09:35 编辑

回复 3# 死水站

1: 一个是常量 SEEK_SET貌似初值没赋?
请参考seek的用法:
  1. seek FILEHANDLE,POSITION,WHENCE
复制代码
Sets FILEHANDLE's position, just like the fseek call of stdio . FILEHANDLE may be an expression whose value gives the name of the filehandle. The values for WHENCE are 0 to set the new position in bytes to POSITION; 1 to set it to the current position plus POSITION; and 2 to set it to EOF plus POSITION, typically negative. For WHENCE you may use the constants SEEK_SET , SEEK_CUR , and SEEK_END (start of the file, current position, end of the file) from the Fcntl module. Returns 1 on success, false otherwise.
SEEK_SET,SEEK_CUR,SEEK_END应该是Fcntl模块内置的常量标示符,不需要初始化赋值

2:逻辑问题
第二个while(<$file>)读取的位置是匹配到/三/所在行的下一行
<$file>实际上就是一个迭代器(iterator),每次读取下一行,
my $position = tell $file, 是利用tell给出当前行的位置,
然后 seek $file, $position, SEEK_SET 把迭代器定位到$position所在的位置。
   

论坛徽章:
0
5 [报告]
发表于 2015-01-07 10:44 |只看该作者
原来是这个意思,前面看的参考说WHENCE是0,1,2,原来和i你这个是一回事啊,哈哈


第二个问题,解释的真清楚!受教咯~

感谢!!!


回复 4# b4and5


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP