引言:perl默认的操作是对单行的操作,但我们在使用perl的匹配或替换的时候,经常会遇到需要跨行操作的情况。这就涉及到跨行匹配。

跨行匹配主要有以下三种方法:

1.修改“$/”

$/表示当前输入记录分隔符,默认情况是换行符

用法:在读入一个文件时while默认情况下是一行一行读的(即以\n作为输入记录分隔符)

有如下的需求,一个log文件:

# Query_time: 0 Lock_time: 0 Rows_sent: 1 Rows_examined: 2

SELECT template

FROM mos_templates_menu

WHERE client_id='0' AND menuid='0';

# Query_time: 0 Lock_time: 0 Rows_sent: 0 Rows_examined: 0

DELETE FROM mos_session

WHERE (time < 1198124076);

# Query_time: 0 Lock_time: 0 Rows_sent: 1 Rows_examined: 285

SELECT count(*) FROM mos_stats_agents

WHERE agent='Mozilla 5.0' AND type='0';

# Query_time: 0 Lock_time: 0 Rows_sent: 0 Rows_examined: 0

UPDATE mos_stats_agents SET hits=(hits+1) WHERE agent='Mozilla 5.0'

AND type='0';

# Query_time: 0 Lock_time: 0 Rows_sent: 1 Rows_examined: 285

SELECT count(*) FROM mos_stats_agents

WHERE agent='Unknown' AND type='1';

# Query_time: 0 Lock_time: 0 Rows_sent: 0 Rows_examined: 0

UPDATE mos_stats_agents SET hits=(hits+1) WHERE agent='Unknown' AND

type='1';

# Query_time: 1 Lock_time: 0 Rows_sent: 1 Rows_examined: 285

SELECT count(*) FROM mos_stats_agents WHERE agent='com' AND

type='2';

要求从log文件中选出Query_time:1的sql语句

以上log文件有如下特点:

比较整齐,每个sql间用空行分隔,或者以;分隔

日志分析要仔细观察日志的特点

复制代码代码如下:

#! /usr/local/bin/perl

#

# 多行日志分析

use strict;

my $logFile = "/shvpn/test/wlj/perl/sqlLog.log";

open FILE, $logFile or die "cant

open logfile $! \n";

$/ = ";"; #

更改默认的输入记录分隔符,或设置为$/ = “”:这样可以以单行或多行分隔

while () { # 每次读入一个多行文本块

if (/\# Query_time: 1[^;]*;\s*/) {  #以文本块进行模式匹配

print "$_ \n";

}

}

以上模式能匹配成功的一个关键是日志文件读取时不是按行,而是按照块读取,即while得到的是一个多行文本块。

2.使用模式匹配修饰符/m

m的作用是将字符串视作多行,这样^和$不仅匹配整个字符串的开头和结尾,也匹配所有换行符的前后

测试代码:

复制代码代码如下:

my $src = "it

is

ok

thanks!";

#my $src = "it \n is \n ok \n

thanks!\n";

if ($src =~ /k$/m || ($src =~ /s$/m || ($src =~ /!$/m || ($src =~

/t$/m) {

print "$src \n";

}

运行的结果都会打印出$src,因为/m修饰符将匹配所有的\n前后。

3.使用模式匹配修饰符/s

s的作用是让”.”匹配所有字符包括换行符

测试代码:

代码如下:

my $src = "it

is

ok

thanks!";

#my $src = "it \n is \n ok \n

thanks!\n";

If ($src =~ /^i.*!$/s) {  print "$src \n";

}

m的作用只影响^和$的匹配,s的作用只影响\n的匹配,所以两者可以混合使用

测试代码:

代码如下:

my $src = "it

is

ok

thanks!";

#my $src = "it \n is \n ok \n

thanks!\n";

If ($src =~ /^i.*k$/sm || $src =~ /^i.*s$/sm) { #

要用.匹配所有的字符(包括换行符,#就必须用/x修饰符)

print "$src \n";

}

修改自:  http://www.jbxue.com/article/4407.html

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐