我有以下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
。
我如何编写正则表达式来提取它们?
发布于 2017-09-18 18:53:05
所示字符串的主要属性是*log*
短语是最后一个。
然后锚定模式,这样我们就不会在中间的某个地方匹配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]*
Update更正了代码中的错误:对于可选的.N
,有+
,而不是*
发布于 2017-09-18 18:10:10
\w+(?=log\b)
匹配一个或多个字母数字字符,后面跟着log
(但不是logging
等)。
如果文件名格式是固定的,则可以使用
\w+(?=log\.\d+\/$)
https://stackoverflow.com/questions/46285645
复制相似问题