首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用Perl解析这个噩梦是可能的吗?

用Perl解析这个噩梦是可能的吗?
EN

Stack Overflow用户
提问于 2009-06-25 16:27:08
回答 4查看 690关注 0票数 1

我正在处理一些文档文件,当复制并粘贴到文本文件中时,会给出以下示例“输出”:

ARTA215高级寿命图(3Cr) (2:2) +工作室1小时。这是绘画与生活的高级研究..。先决条件: ARTA150实验室收费要求ARTA220陶瓷II (3 Cr) (2:2) +工作室1小时。这门课程让学生有机会.实验费用要求ARTA250艺术专题本课程着重于选定的主题.ARTA260投资组合开发(3Cr) (3:0)本课程的目的是.BIOS010生物概念导论(3 is ) (2:2)本课程是一门预备课程,旨在使学生熟悉.BIOS101普通生物学(4 Cr) (3:3)本课程向学生介绍了生物原理。实验室费用要求BIOS102介绍人类生物学(4 Cr) (3:3)本课程是一个介绍.所需的实验费

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

线断了,间距等.是在这个文件的任何时候它会是怎样的。

我最好的猜测是,正则表达式先找到4个大写字母字符,然后是3个数字字符,然后找出接下来的2个字符是否大写。(这说明了课程#,但也排除了在第一项可能说“先决条件”的情况下绊倒的可能性)。在此之后,regex将找到第一个换行符,并在它之后获取所有内容,直到找到下一个课程#为止。这三个字段是一个课程编号、一个课程标题和一个课程描述。课程编号和标题总是在同一条线上,下面的描述就是一切。

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

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

就像我说的,这是一场噩梦,但我想让它自动化,而不是每次生成文件时都要清理某个人。

EN

回答 4

Stack Overflow用户

发布于 2009-06-25 16:42:15

尝试:

代码语言:javascript
复制
my $course;
my @courses;
while ( my $line = <$input_handle> ) {
    if ( $line =~ /^([A-Z]{4}\d+)\s+([A-Z]{2}.*)/ ) {
        $course = [ "$1", "$2" ];
        push @courses, $course;
    }
    elsif ($course) {
        $course->[2] .= $line
    }
    else {
        # garbage before first course in file
        next
    }
}

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

票数 7
EN

Stack Overflow用户

发布于 2009-06-25 16:57:50

我有大致相同的想法,as Gbacon使用段落模式,因为这将整齐地将文件块为您记录。他打字更快,但我写了一本,下面是我的妙处:

代码语言:javascript
复制
#!/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";
}

正如某事物在对格培根的回答所作的评论中指出的那样,段落模式在这里可能行不通。如果不是,算了吧。

票数 4
EN

Stack Overflow用户

发布于 2009-06-25 16:38:53

正则表达式在这方面可能有些过分,因为模式看起来很简单:

代码语言:javascript
复制
[course]
[description]
{Prerequisites}
{Lab Fee Required}

其中课程是由

代码语言:javascript
复制
[course#] [course title] {# Cr} [etc/don't care]

而course#仅仅是前7个字符。

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

代码语言:javascript
复制
//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)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1044876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档