微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

regex – Perl用字符串中的“x”替换数字,但仅在一个特定位置

我正在解析填充各种错误的日志文件.这些是网络错误,这意味着客户在格式化我们网站的日期时蠢蠢欲动.日志看起来像这样:
Error 123: Customer 2: Bad Date [17/12/2014]
Error 123: Customer 2: Bad Date [19/12/2014]
Error 123: Customer 1: Bad Date [123/23/222]
Error 123: Customer 2: Bad Date [null]
Error 123: Customer 6: Bad Date [12/14:]
Error 123: Customer 6: Bad Date [12/16:]

现在,前两个对同一个客户来说真的是同一个错误.这两行,日期报告为DD / MM / YYYY而不是YYYY / MM / DD,所以我不需要两次报告此错误.最后两行对于同一客户也是同样的错误.使用过的MM / DD并离开了当年.即使我之前报告过客户#2的错误日期错误,空日期也是另一个错误.在某个地方,他们正在通过一个空日期.

我想做的是用这种方式比较线条:

Error 123: Customer 2: Bad Date [xx/xx/xxxx]
Error 123: Customer 2: Bad Date [xx/xx/xxxx]
Error 123: Customer 1: Bad Date [xxx/xx/xxx]
Error 123: Customer 2: Bad Date [null]
Error 123: Customer 6: Bad Date [xx/xx:]
Error 123: Customer 6: Bad Date [xx/xx:]

现在,很容易看出前两行和后两行真的是同一个错误.问题是如何使用正则表达式执行此操作.我想更改[和]到x之间的所有数字,但我不想触及字符串的其余部分,因此我不想将错误或客户编号转换为x.

我第一次尝试:

$error =~ s/(\[.*?)\d/$1x/g;

但这只触及括号中的第一个数字.我已经尝试过没有非贪婪的限定符,但这只涉及最后一个角色.

我可以这样做:

$error =~ s/\d/x/g;

但是,用x取代所有出现的数字会破坏我的错误号和客户号.

我可以一遍又一遍地传递错误行,直到没有更换:

while ( my $error = <DATA> ) {
    chomp $error;
    while ( $error =~ s/(\[.*?)\d/$1x/ ) {
        1;
    }
    say qq(Error: "$error");
}

但是必须有一种方法可以做到这一点,而不必多次遍历while循环.

有没有办法用x有效地替换所有出现的数字,但只能在两个方括号之间?

解决方法

我会用这个解决方案:
$error =~ s{(\[ [^\]]+ \])}{
  (my $date = $1) =~ tr/0-9/x/;
  $date;
}ex;

如果没有可重入的正则表达式引擎,这将无法在旧的perls中使用.显然,我错了.我用新鲜的brewed perl 5.10.1尝试了这个代码,它运行得很好.

或者,您可以滥用左值子句:

if ($error =~ /\[/gc) {
  my $start  = pos $error;
  my $length = index($error,']',$start) - $start;
  substr($error,$start,$length) =~ tr/0-9/x/;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


1. 如何去重 #!/usr/bin/perl use strict; my %hash; while(&lt;&gt;){ chomp; print &quot;$_n&quot; unless
最近写了一个perl脚本,实现的功能是将表格中其中两列的数据进行拼凑,然后将拼凑后的数据用“|”连接在一起。表格内容如下: 员工号码员工姓名职位入职日期1001张三销售1980/12/17 0:00:
表的数据字典格式如下:如果手动写MySQL建表语句,确认麻烦,还不能保证书写一定正确。写了个Perl脚本,可快速构造MySQL脚本语句。脚本如下:#!/usr/bin/perluse strict;m
巡检类工作经常会出具日报,最近在原有日报的基础上又新增了一个表的数据量统计日报,主要是针对数据库中使用较频繁,数据量又较大的31张表。该日报有两个sheet组成,第一个sheet是数据填写,第二个sh
在实际生产环境中,常常需要从后台日志中截取报文,报文的形式类似于.........一个后台日志有多个报文,每个报文可由操作流水唯一确定。以前用AWK写过一个,程序如下:beginline=`awk &
最近写的一个perl程序,通过关键词匹配统计其出现的频率,让人领略到perl正则表达式的强大,程序如下:#!/usr/bin/perluse strict;my (%hash,%hash1,@arra
忍不住在 PerlChina 邮件列表中盘点了一下 Perl 里的 Web 应用框架(巧的是 PerlBuzz 最近也有一篇相关的讨论帖),于是乎,决定在我自己的 blog 上也贴一下 :) 原生 CGI/FastCGI 的 web app 对于较小的应用非常合适,但稍复杂一些就有些痛苦,但运行效率是最高的 ;) 如果是自己用 Perl 开发高性能的站,多推荐之。 Catalyst, CGI::A
bless有两个参数:对象的引用、类的名称。 类的名称是一个字符串,代表了类的类型信息,这是理解bless的关键。 所谓bless就是把 类型信息 赋予 实例变量。 程序包括5个文件: person.pm :实现了person类 dog.pm :实现了dog类 bless.pl : 正确的使用bless bless.wrong.pl : 错误的使用bless bless.cc : 使用C++语言实
gb2312转Utf的方法: use Encode; my $str = "中文"; $str_cnsoftware = encode("utf-8", decode("gb2312", $str));   Utf转 gb2312的方法: use Encode; my $str = "utf8中文"; $str_cnsoftware = encode("gb2312", decode("utf-8
  perl 计算硬盘利用率, 以%来查看硬盘资源是否存在IO消耗cpu资源情况; 部份代码参考了iostat源码;     #!/usr/bin/perl use Time::HiRes qw(gettimeofday); use POSIX; $SLEEPTIME=3; sub getDiskUtl() { $clock_ticks = POSIX::sysconf( &POSIX::_SC_