在Perl中提取字符串的某些部分

时间:2017-09-18 18:08:29

标签: regex perl

我有以下Perl字符串。长度和图案是不同的。该文件始终名为*log.999

my $file1 = '/user/mike/desktop/sys/syslog.1';
my $file2 = '/user/mike/desktop/movie/dnslog.2';
my $file3 = '/haselog.3';
my $file4 = '/user/mike/desktop/movie/dns-sys.log'

我需要在log之前提取单词。在这种情况下,sysdnshasedns-sys

如何编写正则表达式来提取它们?

2 个答案:

答案 0 :(得分:2)

\w+(?=log\b)

匹配log后面的一个或多个字母数字字符(但不是logging等。)

如果文件名格式是固定的,您可以使用

使正则表达式更可靠
\w+(?=log\.\d+\/$)

答案 1 :(得分:1)

显示字符串的主要属性是*log*短语 last

然后锚定模式,这样我们就不会匹配中间某处的log

my ($name) = $string =~ /(\w+)log\.[0-9]+$/;

如果.N扩展名是可选的

my ($name) = $string =~ /(\w+)log(?:\.[0-9]+)?$/;

以上使用\w+模式捕获log之前的文本。但该文字可能还包含非字字符(-.等),在这种情况下,我们会使用[^/]+来捕获最后一个/之后的所有字符,如在Abigail's answer中指出。 .N可选,评论中的每个问题

my ($name) = $string =~ m{ ([^/]+) log (?: \.[0-9]+ )? $}x;

我在其中添加了}x修饰符,其中忽略了内部空格,这有助于提高可读性。

我使用除/之外的一组分隔符,以便能够在不转义它的情况下使用/,然后m是强制性的。 [^...]是一个否定字符类,匹配里面列出的任何字符 。因此,[^/]+log会匹配/之前不是log的所有连续字符。

非捕获组 (?: ... )将模式分组,以便?适用于整个组,但不会不必要地捕获它们。

(?:\.[0-9]+)?模式是专门编写的,因此不允许log.(点后没有任何内容)和log5之类的内容。但如果这些是可以接受的,请将其更改为更简单的\.?[0-9]*

更新更正了代码中的拼写错误:对于可选.N,有+,而不是*