Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.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 可以用Perl解析这个噩梦吗?_Regex_Perl_Parsing - Fatal编程技术网

Regex 可以用Perl解析这个噩梦吗?

Regex 可以用Perl解析这个噩梦吗?,regex,perl,parsing,Regex,Perl,Parsing,我正在处理某个文档文件,当复制并粘贴到文本文件中时,该文件将提供以下示例“输出”: 我希望能够解析它,以便生成3个字段,并将值输出到.csv文件中 换行符、间距等。。。就是在这个文件中的任何一点。 我最好的猜测是正则表达式先找到4个大写的alpha字符,然后再找到3个num字符,然后找出接下来的2个字符是否大写。这说明了课程的原因,但也排除了在第一个条目中可能说是先决条件时绊倒的可能性。在此之后,正则表达式会找到第一个换行符,并在找到下一个课程之前获取它之后的所有内容。这3个字段是课程编号、课程

我正在处理某个文档文件,当复制并粘贴到文本文件中时,该文件将提供以下示例“输出”:

我希望能够解析它,以便生成3个字段,并将值输出到.csv文件中

换行符、间距等。。。就是在这个文件中的任何一点。 我最好的猜测是正则表达式先找到4个大写的alpha字符,然后再找到3个num字符,然后找出接下来的2个字符是否大写。这说明了课程的原因,但也排除了在第一个条目中可能说是先决条件时绊倒的可能性。在此之后,正则表达式会找到第一个换行符,并在找到下一个课程之前获取它之后的所有内容。这3个字段是课程编号、课程标题和课程描述。课程编号和标题始终在同一行,描述在下面

示例最终结果将包含3个字段,我猜这些字段可以存储到3个数组中:

"ARTA215","ADVANCED LIFE DRAWING (3 Cr) (2:2)  + Studio 1 hr.","This advanced study in drawing with the life .... Prerequisite: ARTA150 Lab Fee Required"

正如我所说,这是一场噩梦,但我想自动完成这一过程,而不是在每次生成文件后都有人清理文件。

考虑以下示例,该示例依赖于Perl认为的段落中完全包含的课程描述块:

#! /usr/bin/perl

$/ = "";
my $record_start = qr/
  ^            # starting with a newline
  \s*          # allow optional leading whitespace
  ([A-Z]+\d+)  # capture course tag, e.g., ARTA215
  \s+          # separating whitespace
  (.+?)        # course title on rest of line
  \s*\n        # consume trailing whitespace
/mx;

while (<>) {
  my($course,$title);
  if (s/\A$record_start//) {  # fix Stack Overflow highlighting /
    ($course,$title) = ($1,$2);
  }
  elsif (s/(?s:^.+?)(?=$record_start)//) {  # ditto /
    redo;
  }
  else {
    next;
  }

  my $desc;
  die unless s/^(.+?)(?=$record_start|\s*$)//s;
  (my $desc = $1) =~ s/\s*\n\s*/ /g;
  for ($course, $title, $desc) {
    s/^\s+//; s/\s+$//; s/\s+/ /g;
  }
  print join("," => map qq{"$_"} => $course, $title, $desc), "\n";
  redo if $_;
}
当输入样本时,它会输出

"ARTA215","ADVANCED LIFE DRAWING (3 Cr) (2:2) + Studio 1 hr.","This advanced study in drawing with the life .... Prerequisite: ARTA150 Lab Fee Required" "ARTA220","CERAMICS II (3 Cr) (2:2) + Studio 1 hr.","This course affords the student the opportunity to ex... Lab Fee Required" "ARTA250","SPECIAL TOPICS IN ART","This course focuses on selected topic...." "ARTA260","PORTFOLIO DEVELOPMENT (3 Cr) (3:0)","The purpose of this course is to pre...." "BIOS010","INTRODUCTION TO BIOLOGICAL CONCEPTS (3IC) (2:2)","This course is a preparatory course designed to familiarize the begi...." "BIOS101","GENERAL BIOLOGY (4 Cr) (3:3)","This course introduces the student to the principles of mo... Lab Fee Required" "BIOS102","INTRODUCTION TO HUMAN BIOLOGY (4 Cr) (3:3)","This course is an introd.... Lab Fee Required"
考虑以下示例,该示例依赖于课程描述块完全包含在Perl认为的段落中:

#! /usr/bin/perl

$/ = "";
my $record_start = qr/
  ^            # starting with a newline
  \s*          # allow optional leading whitespace
  ([A-Z]+\d+)  # capture course tag, e.g., ARTA215
  \s+          # separating whitespace
  (.+?)        # course title on rest of line
  \s*\n        # consume trailing whitespace
/mx;

while (<>) {
  my($course,$title);
  if (s/\A$record_start//) {  # fix Stack Overflow highlighting /
    ($course,$title) = ($1,$2);
  }
  elsif (s/(?s:^.+?)(?=$record_start)//) {  # ditto /
    redo;
  }
  else {
    next;
  }

  my $desc;
  die unless s/^(.+?)(?=$record_start|\s*$)//s;
  (my $desc = $1) =~ s/\s*\n\s*/ /g;
  for ($course, $title, $desc) {
    s/^\s+//; s/\s+$//; s/\s+/ /g;
  }
  print join("," => map qq{"$_"} => $course, $title, $desc), "\n";
  redo if $_;
}
当输入样本时,它会输出

"ARTA215","ADVANCED LIFE DRAWING (3 Cr) (2:2) + Studio 1 hr.","This advanced study in drawing with the life .... Prerequisite: ARTA150 Lab Fee Required" "ARTA220","CERAMICS II (3 Cr) (2:2) + Studio 1 hr.","This course affords the student the opportunity to ex... Lab Fee Required" "ARTA250","SPECIAL TOPICS IN ART","This course focuses on selected topic...." "ARTA260","PORTFOLIO DEVELOPMENT (3 Cr) (3:0)","The purpose of this course is to pre...." "BIOS010","INTRODUCTION TO BIOLOGICAL CONCEPTS (3IC) (2:2)","This course is a preparatory course designed to familiarize the begi...." "BIOS101","GENERAL BIOLOGY (4 Cr) (3:3)","This course introduces the student to the principles of mo... Lab Fee Required" "BIOS102","INTRODUCTION TO HUMAN BIOLOGY (4 Cr) (3:3)","This course is an introd.... Lab Fee Required"
正则表达式在这方面可能有些过分,因为其模式似乎很简单:

[course]
[description]
{Prerequisites}
{Lab Fee Required}
其中[课程]由

[course#] [course title] {# Cr} [etc/don't care]
这门课只是前7个字符

因此,您可以使用简单的状态机扫描文件,例如:

//NOTE: THIS IS PSEUDOCODE
s = 'parseCourse'
f = openFile(blah)
l = readLine(f)
while (l) {
    if (s=='parseCourse') {
        if (l.StartsWith('Prerequisite:')) {
            extractPrerequisite(l)
        }
        else if (l.StartsWith('Lab Fee Required')) {
            extractLabFeeRequired(l)
        }
        else {
            extractCourseInfo(l)
            s='parseDescription'
        }
    }
    else if (s=='parseDescription') {
        extractDescription(l)
        s='parseCourse'
    }
    l = readLine(f)
}
close(f)

正则表达式在这方面可能有些过分,因为其模式似乎很简单:

[course]
[description]
{Prerequisites}
{Lab Fee Required}
其中[课程]由

[course#] [course title] {# Cr} [etc/don't care]
这门课只是前7个字符

因此,您可以使用简单的状态机扫描文件,例如:

//NOTE: THIS IS PSEUDOCODE
s = 'parseCourse'
f = openFile(blah)
l = readLine(f)
while (l) {
    if (s=='parseCourse') {
        if (l.StartsWith('Prerequisite:')) {
            extractPrerequisite(l)
        }
        else if (l.StartsWith('Lab Fee Required')) {
            extractLabFeeRequired(l)
        }
        else {
            extractCourseInfo(l)
            s='parseDescription'
        }
    }
    else if (s=='parseDescription') {
        extractDescription(l)
        s='parseCourse'
    }
    l = readLine(f)
}
close(f)
尝试:

这将生成一个数组,正如我所理解的那样。对我来说,拥有一个散列数组甚至一个散列数组更有意义。

试试:


这将生成一个数组,正如我所理解的那样。对我来说,拥有一个散列数组甚至一个散列数组会更有意义。

我的想法与使用段落模式大致相同,因为这样可以为您将文件整齐地分块到记录中。他打字快了,但我写了一个,所以我有个窍门:

#!/usr/bin/env perl
use strict;
use warnings;

local $/ = "";

my @items;
while (<>) {
  my( $course, $description ) = (split /\n/, $_)[0, 1];
  my( $course_id, $name ) = ($course =~ m/^(\w+)\s+(.*)$/);
  push @items, [ $course_id, $name, $description ];
}

for my $record (@items) {
  print "Course id: ", $record->[0], "\n";
  print "Name and credits: ", $record->[1], "\n";
  print "Description: ", $record->[2], "\n";
}

正如伊斯特在对巴孔回答的评论中指出的那样,段落模式在这里可能不起作用。如果没有,没关系。

我的想法与使用段落模式大致相同,因为这样可以将文件整齐地分块到记录中。他打字快了,但我写了一个,所以我有个窍门:

#!/usr/bin/env perl
use strict;
use warnings;

local $/ = "";

my @items;
while (<>) {
  my( $course, $description ) = (split /\n/, $_)[0, 1];
  my( $course_id, $name ) = ($course =~ m/^(\w+)\s+(.*)$/);
  push @items, [ $course_id, $name, $description ];
}

for my $record (@items) {
  print "Course id: ", $record->[0], "\n";
  print "Name and credits: ", $record->[1], "\n";
  print "Description: ", $record->[2], "\n";
}
#!/usr/bin/perl
$/ = "\n\n";
$FS = "\n";
$, = ',';
while (<>) {
    chomp;
    @F = split($FS, $_);
    print join($,,@F) ."\n";
}

正如伊斯特在对巴孔回答的评论中指出的那样,段落模式在这里可能不起作用。如果不是,没关系。

部门总是四个字母吗?没有CS系,或者它有另一个名字吗?你能依靠课程描述从一个新的段落开始吗,即在两行换行后?我不认为这是家庭作业,我认为这是一个大学生试图解析注册网站。我无法想象任何教授会试图教他们的学生这是正确的机器可读输入…@mmyers是的@gbacon描述始终从课程编号-标题行下的行开始@保罗:当然不是家庭作业,也不是学生。我正在研究一种自动获取市场营销文档并将其插入我们正在工作的新表的方法on@Cheese:在这种情况下,请在您的帖子中的BIOS010之前添加一个空格。段落模式$/=;在这种情况下是一种选择。部门是否总是四个字母?没有CS系,或者它有另一个名字吗?你能依靠课程描述从一个新的段落开始吗,即在两行换行后?我不认为这是家庭作业,我认为这是一个大学生试图解析注册网站。我无法想象任何教授会试图教他们的学生这是正确的机器可读输入…@mmyers是的@gbacon描述始终从课程编号-标题行下的行开始@保罗:当然不是家庭作业,也不是学生。我正在研究一种自动获取市场营销文档并将其插入我们正在工作的新表的方法on@Cheese:在这种情况下,请在您的帖子中的BIOS010之前添加一个空格。段落模式$/=;是本例中的一个选项。我认为您没有看到问题上的perl标记:如果它有$,可能会被误认为perl。当然,s/openFile/open/和s/readLine/readLine/etc除外-@你一定是在开玩笑。伪代码!没有人付钱让我写Perl,这个小问题也不需要任何特定于Perl的功能。我认为您没有看到问题上的Perl标记:如果它有$,可能会被误认为是Perl。
#!/usr/bin/perl
$/ = "\n\n";
$FS = "\n";
$, = ',';
while (<>) {
    chomp;
    @F = split($FS, $_);
    print join($,,@F) ."\n";
}


当然,s/openFile/open/和s/readLine/readLine/etc除外-@你一定是在开玩笑。伪代码!没有人付钱让我写Perl,这个小问题也不需要任何特定于Perl的功能。在有人评论之前,这些都不是无用的。你能找出原因吗?我会咬一口:引号是必要的,因为$2可能包含空格吗?@Telemachus:不。区别比这更微妙,只有在特殊情况下用户才能看到,而不取决于$1或$2中的字符。当然,我们总是可以通过在末尾添加类似这样的内容来修复一段完全可以理解的代码,以生成所需的输出:print join\n,map{join',,map{s/\r\124n//gs;qq{$}@$}@courses@莱昂纳多·赫雷拉:谢谢;不知何故,我完全错过了问题的.csv部分。考虑到你的一段好代码要附加到我的面前。在别人评论之前,这是没有用处的。你能找出原因吗?我会咬一口:引号是必要的,因为$2可能包含空格吗?@Telemachus:不。区别比这更微妙,只有在特殊情况下用户才能看到,而不取决于$1或$2中的字符。当然,我们总是可以通过在末尾添加类似这样的内容来修复一段完全可以理解的代码,以生成所需的输出:print join\n,map{join',,map{s/\r\124n//gs;qq{$}@$}@courses@莱昂纳多·赫雷拉:谢谢;不知何故,我完全错过了问题的.csv部分。考虑你的一段好代码要附加到我的。所有的答案都有永久链接,所以你可以链接到他们而不是仅仅引用它们。此外,下面的内容也没有什么意义,因为答案是按有用性排序的。是的,我总是忘了上面和下面都是相关术语。上面和下面都是相关术语,但它们在这里有一个元相对论;所有答案都有永久链接,因此您可以链接到它们,而不仅仅是引用它们。此外,下面的内容也没有什么意义,因为答案是按有用性排序的。是的,我总是忘了上面和下面都是相关术语。上面和下面都是相关术语,但它们在这里有一个元相对论;哟,培根。。。。这看起来很好吃。假设我的pl文件位于一个目录中,所有这些课程、标题和描述都在一个txt文件中。如何修改您的代码以查找new.txt?我仍然在搜索如何将我的txt输入你的codebeast的代码…@CheeseConQueso假设你在一个包含my.pl和new.txt的目录中,只需运行perl my.pl new.txthahaha。。。当陌生人帮助你时,你很容易爱上他们。。。认为巴肯是个男人是个性别歧视者。。也许是某个辣妹拍了一张随机男朋友的照片,所以没人打扰她!哟,培根。。。。这看起来很好吃。假设我的pl文件位于一个目录中,所有这些课程、标题和描述都在一个txt文件中。如何修改您的代码以查找new.txt?我仍然在搜索如何将我的txt输入你的codebeast的代码…@CheeseConQueso假设你在一个包含my.pl和new.txt的目录中,只需运行perl my.pl new.txthahaha。。。当陌生人帮助你时,你很容易爱上他们。。。认为巴肯是个男人是个性别歧视者。。也许是某个辣妹拍了一张随机男朋友的照片,所以没人打扰她!真正地我星期一要查一下。。。我就要下班了。。。当捕食者启动自毁程序时,while循环上方的顶部看起来像是捕食者的手腕,真的吗?我星期一要查一下。。。我就要下班了。。。当捕食者启动自毁程序时,while环上方的顶部看起来像是捕食者的手腕