我正试图从这个示例文本中提取最好的工作标题:
数据科学家
最佳薪酬工作排名第一
5,100预计就业250,000美元中位数薪酬0.5%失业率
程序员
#2在……
你没有占用空格(如 Data Scientist )考虑到:
Data Scientist
^\w+.*$\R+#(\d+)
看到 的 regex101.com上的演示 强> 。
\R
(?>\r\n|\n|\r|\f|\x0b|\x85)
为什么不逐行处理,简单易行
use warnings; use strict; use feature 'say'; my $file = shift || die "Usage: $0 file\n"; open my $fh, '<', $file or die "Can't open $file: $!"; my (@jobs, $prev_line); while (my $line = <$fh>) { chomp $line; next if not $line =~ /\S/; if ($line =~ /^\s*#[0-9]/) { push @jobs, $prev_line; } $prev_line = $line; } say for @jobs;
这取决于要求 #N line是作业标题后的第一个非空行。
#N
它打印
Data Scientist Programmer SAP Module Consultant
问题并不是说排名是否也被通缉,但正则表达式中有一个暗示它们可能是。然后,假设文件中的排序是“正确的”,您可以迭代数组索引并使用它们的索引(排名)打印元素(标题)。
或者,确定,在正则表达式中捕获它们, /^\s*#([0-9]+)/ 。然后,您可以直接打印标题及其排名,或者可能将它们存储在具有键值对的散列中 rank => title 。
/^\s*#([0-9]+)/
rank => title
至于正则表达式,有一些必要的更正。要在匹配之前编写正则表达式,这是一个好主意,你想要的 QR 运营商。要使用多行字符串,您需要使用 /m 修改。 (看到 perlretut 。)正则表达式本身需要修复。例如
/m
my $regex = qr/^(.+)?(?:\n\s*)+\n\s*#\s*[0-9]/m; my @titles = $content =~ /$regex/g
什么捕获一行后跟至少一个空行然后 #N 在另一条线上。
如果还需要标题的排名,那么也可以捕获它,并存储在哈希中
my $regex = qr/^(.+)?(?:\n\s*)+\n\s*#\s*([0-9]+)/m; my %jobs = reverse $content =~ /$regex/g;
或者最好不要推它 reverse - 匹配列表,但迭代通过对
reverse
my %jobs; while ($content =~ /$regex/g) { $jobs{$2} = $1; }
因为我们可以在每次迭代时检查我们的“捕获”,进行其他处理等。然后你可以按顺序对按键进行排序
say "#$_ $jobs{$_}" for sort { $a <=> $b } keys %jobs;
并且通常根据需要按他们的等级选择工作。
我认为这里的正则表达式比第一个程序要复杂得多,这是公平的。