在模式之后匹配修改字符

时间:2016-08-11 22:22:27

标签: perl

我差不多20年前做过这个,所以我对Perl的遗忘很多,而且我没有找到谷歌的回答。

我有一个包含许多Times Ten DB create hash index语句

的文件
create unique hash index on MYSCHEMA.MYTABLE (Col1, Col2)  pages=####;
create hash index on MYSCHEMA.ANOTHER_TABLE (Col1, Col2)  pages=####;

我有一个由表名称键入的哈希值,其中包含“pages = ###”的所需值。

我已将该行正确读入字符串变量,我需要知道如何将index on MYSCHEMA.后面的表名转换为变量。

另外,如何替换pages=####中的数字?

2 个答案:

答案 0 :(得分:4)

在列表上下文中使用匹配来提取表名。

#!/usr/bin/perl
use warnings;
use strict;

my @lines = (
    "create unique hash index on MYSCHEMA.MYTABLE (Col1, Col2)  pages=####;\n",
    "create hash index on MYSCHEMA.ANOTHER_TABLE (Col1, Col2)  pages=####;\n"
);

my %pages = ( MYTABLE => 12,
              ANOTHER_TABLE => 42,
);

for my $line (@lines) {
    my ($table) = $line =~ /index on MYSCHEMA\.(\w+)/;
    $line =~ s/pages=####/pages=$pages{$table}/;
    print $line;
}

答案 1 :(得分:4)

提取架构名称

my ($schema_name) = $line =~ s/MYSCHEMA\.([A-Z_]+)/;

替换pages=

后面的数字
$line =~ s/(pages=)(#+)/$1$number_replacement/;

这适用于对行结构的一些假设 - 模式名称仅包含大写或下划线,并且这些数字跟随=不带空格。

更好的方式,由Borodin在评论中提供

$line =~ s/pages=\K#+/$number_replacement/;

\K正向后看 (?<=pattern)的一种特殊形式,零宽度断言指定的模式在当前匹配之前位置。此表单也会丢弃之前的所有匹配项,因此上面的替换不会触及pages=部分。因此,不需要任何捕获组。请参阅外观断言in perlretut\K in perlre(向下滚动一下)。