Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 不规则新行的多行匹配_Regex_Perl - Fatal编程技术网

Regex 不规则新行的多行匹配

Regex 不规则新行的多行匹配,regex,perl,Regex,Perl,我有一个文本文件,其中有许多条目如下: [...] Wind: 83,476,224 Solution: (category,runs)~ 0.235,6.52312667,~ 0.98962,14.33858333,~ sdasd,cccc,~ 0.996052905,sdsd EnterValues: 656,136,1 Speed: 48,32 State: 2,102,83,476,224 [...] 我想从以上部分摘录: Solution: (category,runs)~ 0.23

我有一个文本文件,其中有许多条目如下:

[...]
Wind: 83,476,224
Solution: (category,runs)~
0.235,6.52312667,~
0.98962,14.33858333,~
sdasd,cccc,~
0.996052905,sdsd
EnterValues: 656,136,1
Speed: 48,32
State: 2,102,83,476,224
[...]
我想从以上部分摘录:

Solution: (category,runs)~
0.235,6.52312667,~
0.98962,14.33858333,~
sdasd,cccc,~
0.996052905,sdsd
如果在每个
解决方案:
之后都存在
EnterValues:
,这将很简单,但不幸的是,它不存在。有时是速度,有时是不一样的。我不知道如何构造正则表达式的结尾(我假设它应该是这样的:
Solution:.*?(?)


我的文件已\n作为新行的分隔符。

我看到您首先将所有文件读取到内存,但这不是一个好的做法。请尝试使用触发器运算符:

while ( <$fh> ) {
   if ( /Solution:/ ... !/~$/ ) {
      print $_, "\n";
   }
}
while(){
如果(/解决方案:/…!/~$/){
打印美元“\n”;
}
}

我现在无法测试它,但我认为这应该可以正常工作。

您需要的是应用一个具有正则表达式功能的“记录分隔符”。不幸的是,您不能使用
$/
,因为它不能是正则表达式。但是,您可以将整个文件读入一行,然后使用正则表达式拆分该行:

use strict;
use warnings;
use Data::Dumper;

my $str = do { 
    local $/;   # disable input record separator
    <DATA>;     # slurp the file
};
my @lines = split /^(?=\pL+:)/m, $str;  # lines begin with letters + colon
print Dumper \@lines;

__DATA__
Wind: 83,476,224
Solution: (category,runs)~
0.235,6.52312667,~
0.98962,14.33858333,~
sdasd,cccc,~
0.996052905,sdsd
EnterValues: 656,136,1
Speed: 48,32
State: 2,102,83,476,224

我想您将对这些变量进行某种后处理,但我将把它留给您。从这里开始的一种方法是在换行符上拆分值。

您可以从
解决方案
匹配到word,后跟冒号

my ($solution) = $text =~ /(Solution:.*?) \w+: /xs;

此解决方案要求您知道
solution
位于任何一个关键字之前。@TLP,是的,但可能可以通过修改第二个regexp:)@her_dom,是的,请查看TLP的回答。此外,它还将包括打印中下一个值的标题。关闭翻转的更好的正则表达式可能是
/^\pL+:/
,但您仍然需要补偿额外的行数。肮脏的黑客:添加一个布尔标志以跳过第一行:D,关闭正则表达式看起来很好,thx。我会更新答案。你能解释一下
\pL+
的作用吗?我能找到它;/
\pL
是字母的字符类
+
是量词,意思是“匹配一次或多次”。您可以在TLP的解决方案中找到
\pL
,但您的解决方案更简单,可以满足我的要求。非常感谢。
my ($solution) = $text =~ /(Solution:.*?) \w+: /xs;