如何从 Perl 中的文本文件中提取/解析表格数据?

2024-05-26

我正在寻找类似的东西HTML::表格提取 http://search.cpan.org/dist/HTML-TableExtract/,只是不适用于 HTML 输入,而是适用于包含采用缩进和间距格式化的“表格”的纯文本输入。

数据可能如下所示:

Here is some header text.

Column One       Column Two      Column Three
a                                           b
a                    b                      c


Some more text

Another Table     Another Column
abdbdbdb          aaaa

不知道任何打包的解决方案,但是假设您可以对文件进行两次传递,那么一些不太灵活的事情就相当简单:(以下是部分 Perlish 伪代码示例)

  • 假设:数据可能包含空格,如果有空格,则不会在 CSV 中引用 - 如果不是这种情况,只需使用Text::CSV(_XS).
  • 假设:没有使用制表符进行格式化。
  • 该逻辑将“列分隔符”定义为 100% 填充有空格的任何连续的垂直行集。
  • 如果偶然每行都有一个空格,该空格是偏移量 M 个字符处的数据的一部分,则逻辑将认为偏移量 M 是列分隔符,因为它无法知道任何更好的情况。它可以更好地了解的唯一方法是,如果您要求列间隔至少为 X 个空格,其中 X>1- 请参阅第二个代码片段。

示例代码:

my $INFER_FROM_N_LINES = 10; # Infer columns from this # of lines
                             # 0 means from entire file
my $lines_scanned = 0;
my @non_spaces=[];
# First pass - find which character columns in the file have all spaces and which don't
my $fh = open(...) or die;
while (<$fh>) {
    last if $INFER_FROM_N_LINES && $lines_scanned++ == $INFER_FROM_N_LINES;
    chomp;
    my $line = $_;
    my @chars = split(//, $line); 
    for (my $i = 0; $i < @chars; $i++) { # Probably can be done prettier via map?
        $non_spaces[$i] = 1 if $chars[$i] ne " ";
    }
}
close $fh or die;

# Find columns, defined as consecutive "non-spaces" slices.
my @starts, @ends; # Index at which columns start and end
my $state = " "; # Not inside a column
for (my $i = 0; $i < @non_spaces; $i++) {
    next if $state eq " " && !$non_spaces[$i];
    next if $state eq "c" && $non_spaces[$i];
    if ($state eq " ") { # && $non_spaces[$i] of course => start column
        $state = "c";
        push @starts, $i;
    } else { # meaning $state eq "c" && !$non_spaces[$i] => end column
        $state = " ";
        push @ends, $i-1;
    }
}
if ($state eq "c") { # Last char is NOT a space - produce the last column end
    push @ends, $#non_spaces;
}

# Now split lines
my $fh = open(...) or die;
my @rows = ();
while (<$fh>) {
    my @columns = ();
    push @rows, \@columns;
    chomp;
    my $line = $_;
    for (my $col_num = 0; $col_num < @starts; $col_num++) {
        $columns[$col_num] = substr($_, $starts[$col_num], $ends[$col_num]-$starts[$col_num]+1);
    }
}
close $fh or die;

现在,如果你要求列间隔至少为 X 个空格,其中 X>1,它也是可行的,但列位置的解析器需要更复杂一些:

# Find columns, defined as consecutive "non-spaces" slices separated by at least 3 spaces.
my $min_col_separator_is_X_spaces = 3;
my @starts, @ends; # Index at which columns start and end
my $state = "S"; # inside a separator
NEXT_CHAR: for (my $i = 0; $i < @non_spaces; $i++) {
    if ($state eq "S") { # done with last column, inside a separator
        if ($non_spaces[$i]) { # start a new column
            $state = "c";
            push @starts, $i;
        }
        next;
    }
    if ($state eq "c") { # Processing a column
        if (!$non_spaces[$i]) { # First space after non-space
                                # Could be beginning of separator? check next X chars!
            for (my $j = $i+1; $j < @non_spaces
                            || $j < $i+$min_col_separator_is_X_spaces; $j++) {
                 if ($non_spaces[$j]) {
                     $i = $j++; # No need to re-scan again
                     next NEXT_CHAR; # OUTER loop
                 }
                 # If we reach here, next X chars are spaces! Column ended!
                 push @ends, $i-1;
                 $state = "S";
                 $i = $i + $min_col_separator_is_X_spaces;
            }
         }
        next;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从 Perl 中的文本文件中提取/解析表格数据? 的相关文章

  • 在 Perl 中优雅地确定系统架构

    我正在寻找一种简单的方法来确定 Perl 5 中的系统是 32 位还是 64 位 我已阅读perlvar来回翻阅手册页 并没有发现包含系统 CPU 架构的变量 编译 Perl 的 CPU 架构将足够接近 这是我最接近的 chomp my a
  • 匹配有限自然数列

    我怎样才能匹配有限自然数 http en wikipedia org wiki Natural number正则表达式系列 所以 要求是 字符串包含数字和空格 作为分隔符 第一个数字是1 每个数字 第一个数字除外 等于前一个数字 1 应该是
  • 标量值错误(使用 IO::Socket)

    这是我当前的代码 usr bin perl w use strict require IO Socket while lt gt chomp my host my header print Connecting to host n my s
  • 使用 Python ast 模块访问语法树中的节点

    我正在玩 python ast 抽象语法树 我编写了以下内容 它访问了 AST 的所有节点 import ast class Py2Neko ast NodeVisitor def generic visit self node print
  • 真实设备中的 Android strace

    我有以下情况 我想监控Android手机上的系统调用 所以 我编写了一个脚本来做到这一点 使用 Android 模拟器可以完美地工作 将应用程序的痕迹写入我的 Ubuntu 上的特定文件中 问题是当我连接一个真实的手机来分析它时 它在结果文
  • 为什么Perl的SUPER调用不使用箭头方法?

    我注意到 当您调用超类的方法时 您需要执行以下操作 my self class gt SUPER new 为什么不是这样 my self class gt SUPER gt new 我怀疑是因为 class gt SUPER gt new
  • Perl - 以相反的顺序逐行读取文件[重复]

    这个问题在这里已经有答案了 可能的重复 如何在 Perl 中从文件末尾读取行 https stackoverflow com questions 303053 how can i read lines from the end of fil
  • Perl6:我怎样才能使所有警告都是致命的?

    我怎样才能使 Perl6 中的所有警告都是致命的 以便脚本在屏幕上出现警告时立即终止 CONTROL when CX Warn note exit 1 更频繁地死亡 该脚本终止于CONTROL when CX Warn note exit
  • Perl 中如何释放内存?

    我的代码如下所示 my var my var new while 1 while my k v each var a sub v var A map var var new keys var new var new B sub a sub
  • 用 C# 解析和查询 SOAP

    我正在尝试解析一个大量命名空间的 SOAP 消息 源也可以在here http tinyurl com n3av6k
  • ANTLR4 在导入时找不到语法

    我正在尝试将 ANTLR4 语法拆分为多个文件 以便我可以更轻松地测试它们 我在 java 项目中使用 gradle 作为构建工具 两种语法都单独正确编译 但是当我将导入添加到我的主语法中时 我收到下一个编译错误 错误 110 kaneko
  • 尝试解解析 json 字符串,但得到 Expected start of the object '{', but had 'EOF' 相反

    我正在尝试使用 kotlin 可序列化将 json 文件解析为列表 这是我的数据类 Serializable data class Book val epub String val fb2 String val mobi String va
  • 解析 (yyyy-MM-dd) 格式的字符串日期

    我有一个 2013 09 18 形式的字符串 我想将其转换为 java util Date 我正在做这个 SimpleDateFormat sdf new SimpleDateFormat yyyy MM dd Date converted
  • 如何在 Perl 中使用 use strict 一次一行处理多行字符串?

    我正在尝试找出 PBP 批准的正确方法来一次一行处理多行字符串 许多 Perl 编码人员建议将多行字符串视为文件句柄 除非您在脚本中使用 use strict 否则它可以正常工作 然后 您会收到编译器发出的警告 提示在使用严格引用时无法使用
  • 迭代哈希数组

    我编写了下面的例程 迭代哈希值 0 7 并打印出每个哈希值中特定键的值 我需要获取每个哈希中 b4 的值 我想取消 0 7 当存在不同数量的哈希值时使用更智能的东西 例如 有时只有 2 个 也可能有 160 个 my out decode
  • less.js - 在解析器回调中获取变量值

    我正在使用 less js 1 3 0 在客户端将 less 解析为 css 在解析器的回调中 我想获取每个变量的值 我尝试了以下方法但没有成功 var data colour red example background color co
  • 使用 SIGINT 默认处理程序时从 system() 返回值

    我遇到了一些奇怪的返回值system 当子进程从终端接收到 SIGINT 时 解释一下 从 Perl 脚本parent pl I used system 运行另一个 Perl 脚本作为子进程 但我还需要通过 shell 运行子进程 所以我使
  • 如何使用 Perl 更改 mysql 密码

    我需要使用 Perl 脚本更改一些 mysql 密码 以下内容在更改数据库条目时有效 但是当我针对 mysql 用户更改修改它时 它将它们重置为空白密码 最后 刷新权限 也很好 但我还没有找到方法 usr bin perl use DBI
  • 使用 Perl 获取 值

    因此 我有一个报告工具 可以在 HTML 文件中输出作业调度统计信息 并且我希望使用 Perl 来使用这些数据 但我不知道如何单步浏览 HTML 表 我知道如何使用 jQuery 来做到这一点 find tr each function v
  • perl-5.10 之前的高效版本相当于 pack("Q>")

    更新 萨尔瓦正确地指出我对 Q 包模板的介绍是错误的 这是 gt 修饰符 不会返回到 5 8 Perl 5 10 引入了 pack 修饰符 gt 对于我使用 Q 的用例 它将一个无符号四边形 64 位 值打包在大尾数法 现在 我正在寻找一个

随机推荐