关于正则表达式:在Perl中提取字符串的某些部分

Extract certain part of a string in Perl

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

1
2
3
4
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

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


1
\\w+(?=log\\b)

匹配一个或多个字母数字字符,后跟log(但不匹配logging等)。

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

使正则表达式更可靠

1
\\w+(?=log\\.\\d+\\/$)


显示的字符串的主要属性是*log*短语是最后一个。

然后锚定模式,因此我们不会在中间的某个位置匹配log

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

而如果.N扩展名是可选的

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

上面使用\\w+模式捕获log之前的文本。但是该文本也可能包含非单词字符(-.等),在这种情况下,我们将使用[^/]+捕获最后一个/之后的所有内容,如阿比盖尔的回答所指出的那样。对于注释中的每个问题,使用.N可选

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

我在其中添加了}x修饰符的地方,其中的空格将被忽略,这有助于提高可读性。

我使用了一组除/以外的定界符,以便能够在内部使用/而不会对其进行转义,然后m是强制性的。 [^...]是否定的字符类,与未在其中列出的任何字符匹配。因此[^/]+log匹配log之前的所有不是/的连续字符。

非捕获组(?: ... )对内部的模式进行分组,因此?适用于整个组,但不必要捕获它们。

(?:\\.[0-9]+)?模式是专门为禁止诸如log.(在点号之后)和log5之类的东西而编写的。但是,如果可以接受,则将其更改为更简单的\\.?[0-9]*

更新纠正了代码中的错字:对于可选的.N,存在+,而不是*