我有一组特定的重复文本块。它们具有动态文件名和动态消息。对于我想要提取消息的每个文件名。
Filename: dynamicFile.txt
Property: some property to neglect
Message: the message I want
Time: dynamicTime
我想在消息之后提取部分,即:the message I want
。
我拥有:以下内容将匹配文件名和时间之间的任何内容。
(?<=Filename: %myFileVar%)(?s)(.*)(?=Time:)
而%myFileVar%
是动态文件变量,我将使用。
现在我需要找到一种方法来在文件名之后省略任何内容,直到消息部分。在这里我不得不忽略:
Property: some property to neglect
Message:
怎么可以这样做?
答案 0 :(得分:2)
use warnings;
use strict;
my $text;
{
local $/;
$text = <DATA>;
}
my $myFileVar = 'dynamicFile.txt';
if ($text =~ /Filename: \Q$myFileVar\E.*?Message: (.*?)\s*Time:/s)
{
print $1;
}
__DATA__
Filename: dynamicFile.txt
Property: some property to neglect
Message: the message I want
Time: dynamicTime
注意:这假定Time:
总是在消息行之后。如果不是这样,那么ikegami的解决方案提供了一种跳过任何其他行的方法。
<强>解释强>
\Q...\E
来包围变量,这使得两者之间的所有内容都可以进行字面处理。如果你不这样做,你的文件名中的点将匹配任何字符。$1
,$2
等。s
)作为开关。 (/s
代替(?s)
)。在模式中打开它是实验性的,只有在需要它才能应用于模式的一部分时才应该使用它。.*?
代替.*
。否则,该模式将匹配文件中第一个Message:
到最后一个Time:
的所有内容。答案 1 :(得分:1)
/
^
Filename: \s* \Q$myFileVar\E \n
(?: (?!Message:) [^\n]*\n )*
Message: \s* ([^\n]*) \n
(?: (?!Time:) [^\n]*\n )*
Time:
/mx
(?: [^\n]*\n )*
会跳过任意数行。
答案 2 :(得分:0)
Perl可以执行\K
Magic
添加迟到的答案,因为我没有看到我最喜欢的解决方案。在Perl正则表达式中,\K
告诉引擎放弃我们到目前为止匹配的所有内容。所以你可以使用这个正则表达式:
(?sm)^Filename:.*?Message: \K[^\r\n]+
甚至:
(?m)^Message: \K[^\r\n]+
请参阅demo。