我正在尝试从以下示例文本中提取薪水最高的职位:
Data Scientist
#1 in Best Paying Jobs
5,100 Projected Jobs $250,000 Median Salary 0.5% Unemployment Rate
Programmer
#2 in Best Paying Jobs
4,000 Projected Jobs $240,000 Median Salary 1.0% Unemployment Rate
SAP Module Consultant
#3 in Best Paying Jobs
3,000 Projected Jobs $220,000 Median Salary 0.2% Unemployment Rate
Run Code Online (Sandbox Code Playgroud)
通过使用以下正则表达式和Perl代码。
use File::Glob;
local $/ = undef;
my $file = @ARGV[0];
open INPUT, "<", $file
or die "Couldn't open file $!\n";
my $content = <INPUT>;
my $regex = "^\w+(\w+)*$\n\n#(\d+)";
my @arr_found = ($content =~ m/^\w+(\w+)*$\n\n#(\d+)/g);
close (INPUT);
Run Code Online (Sandbox Code Playgroud)
Q1:正则表达式仅查找一个单词的标题*。如何使其找到多个单词标题,以及如何将找到的标题转发(即如何正确捕获)到Perl数组中?
Q2:我将正则表达式定义为Perl变量,并尝试将该变量用于正则表达式操作,例如:
my @arr_found = ($content =~ m/"$regex"/g);
Run Code Online (Sandbox Code Playgroud)
但它给了错误。怎么做?
*当我^\w+(\w+)*$\n\n#(\d+)在Sublime Text 2上应用正则表达式时,它仅找到一个单词的标题。
为什么不逐行处理,简单又容易
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;
Run Code Online (Sandbox Code Playgroud)
这取决于该#N行是作业标题之后的第一个非空行的要求。
它打印
数据科学家 程序员 SAP模块顾问
问题并没有说明是否也需要排名,但是正则表达式中暗示可能会排名。然后,假设文件中的顺序是“正确的”,则可以遍历数组索引并使用其索引(等级)打印元素(标题)。
或者可以肯定的是,将它们捕获在正则表达式中/^\s*#([0-9]+)/。然后,您可以直接打印标题及其排名,或者将它们存储在具有键值对的哈希中rank => title。
至于正则表达式,需要一些更正。要在匹配之前编写一个正则表达式,这是一个好主意,您需要qr运算符。要使用多行字符串,您需要使用/m修饰符。(请参阅perlretut。)regex本身需要修复。例如
my $regex = qr/^(.+)?(?:\n\s*)+\n\s*#\s*[0-9]/m;
my @titles = $content =~ /$regex/g
Run Code Online (Sandbox Code Playgroud)
捕获一行,然后至少一行空行,然后再捕获#N另一行。
如果还需要对标题进行排名,则也要对其进行捕获,并将其存储在哈希中
my $regex = qr/^(.+)?(?:\n\s*)+\n\s*#\s*([0-9]+)/m;
my %jobs = reverse $content =~ /$regex/g;
Run Code Online (Sandbox Code Playgroud)
或者最好不要通过reverse-ing匹配列表来推送它,而是遍历配对
my %jobs;
while ($content =~ /$regex/g) {
$jobs{$2} = $1;
}
Run Code Online (Sandbox Code Playgroud)
因为这样我们可以在每次迭代中检查“捕获”,进行其他处理,等等。然后您可以对要排序的键进行排序
say "#$_ $jobs{$_}" for sort { $a <=> $b } keys %jobs;
Run Code Online (Sandbox Code Playgroud)
通常只是根据需要按职位等级选择工作。
我认为可以说这里的正则表达式比第一个程序复杂得多。