我有以下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
之前提取单词。在这种情况下,sys
,dns
,hase
和dns-sys
。
如何编写正则表达式来提取它们?
答案 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
,有+
,而不是*