【发布时间】:2017-03-09 08:10:03
【问题描述】:
我正在寻求有关提取字符串部分的建议,该部分总是使用 perl 和正则表达式作为括号之间的第一个实例数据出现,并将该值分配给变量。
这是确切的情况,我使用 perl 和正则表达式从大学目录中提取 courseID 并将其分配给变量。请考虑以下几点:
- BIO-2109-01 (12345) 生物学简介
- CHM-3501-F2-01 (54321) 化学概论
- IDS-3250-01 (98765) 美国历史 (1860-2000)
- SPN-1234-02-F1 (45678) 西班牙历史 (1900-2010)
典型的格式是 [course-section-name] [(courseID)] [courseName]
我的目标是创建一个脚本,它可以一次获取每个条目,将其分配给一个变量,然后使用正则表达式仅提取 courseID 并将 courseID 分配给一个变量。
我的方法是使用搜索和替换来替换与 '' 不匹配的所有内容,然后将剩下的内容(课程 ID)保存到变量中。以下是我尝试过的一些示例:
$string = "BIO-2109-01 (12345) Introduction to Biology";
($courseID = $string) =~ s/[^\d\d\d\d\d]//g;
print $courseID;
结果:21090112345 --- 打印 course-section-name 和 courseID
$string = "BIO-2109-01 (12345) Introduction to Biology";
$($courseID = $string) =~ s/[^\b\(\d{5}\)]\b//g;
print $courseID;
结果:210901(12345) --- 打印 course-section-name、parens 和 courseID
所以我在搜索和替换方面运气不佳 - 但是我找到了这个金块:
\(([^\)]+)\)
在http://regexr.com/ 上将匹配括号部分。但是,它也会匹配多个参数,例如 (abc)。
我现在不确定如何做这样的事情:
$string = "BIO-2109-01 (12345) Introduction to Biology";
($courseID = $string) =~ [magicRegex_goes_here];
print courseID;
结果 12345
或者,更好:
$string = IDS-3250-01 (98765) History of US (1860-2000)
($courseID = $string) =~ [magicRegex_goes_here];
print courseID;
结果 98765
任何建议或指导将不胜感激。我已经尝试了我所知道的一切,并且可以研究正则表达式来解决这个问题。如果有更多信息我可以包括,请询问。
更新
use warnings 'all';
use strict;
use feature 'say';
my $file = './data/enrollment.csv'; #File this script generates
my $course = ""; #Complete course string [name-of-course] [(courseID)] [course_name]
my @arrayCourses = ""; #Array of courseIDs
my $i = ""; #i in for loop
my $courseID = ""; #Extracted course ID
my $userName = ""; #Username of person we are enrolling
my $action = "add,"; #What we are doing to user
my $permission = "teacher,"; #What permissions to assign to user
my $stringToPrint = ""; #Concatinated string to write to file
my $n = "\n"; #\n
my $c = ","; #,
#BEGIN PROGRAM
print "Enter the username \n";
chomp($userName = <STDIN>); #Get the enrollee username from user
print "\n";
print "Enter course name and press enter. Enter 'x' to end. \n"; #prompt for course names
while ($course ne 'x') {
chomp($course = <STDIN>);
if ($course ne "x") {
if (($courseID) = ($course =~ /[^(]+\(([^)]+)\)/) ) { #nasty regex to extract courseID - thnx PerlDuck and zdim
push @arrayCourses, $courseID; #put the courseID into array
}
else {
print "Cannot process last entry check it";
}
}
else {
last;
}
}
shift @arrayCourses; #Remove first entry from array - add,teacher,,username
open(my $fh,'>', $file); #open file
for $i (@arrayCourses) #write array to file
{
$stringToPrint= join "", $action, $permission, $i, $c, $userName, $n ;
print $fh $stringToPrint;
}
close $fh;
这样就可以了!欢迎提出建议或改进!感谢@PerlDuck 和@zdim
【问题讨论】:
-
+1 用于展示您的尝试!请注意,
[…]表示 字符类,基本上表示[和]之间的字符中的一个(任意)字符。所以[ab\dL]匹配其中一个a、b、一个数字或L,而不是全部匹配。 -
提醒,以防万一出现问题,请参阅:What should I do when someone answers my question?
标签: regex string perl scripting