【问题标题】:Pull specific information from a long list with Perl使用 Perl 从一长串列表中提取特定信息
【发布时间】:2011-02-19 07:25:00
【问题描述】:

我必须在这里处理的文件是 LDAP 提取的结果,但我最终需要将信息格式化为电子表格可以使用的东西。

所以,数据如下:

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: John Doe
name: ##userName

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: Jane Doe Jr
name: ##userName

DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
DataDataDataDataDataDataDataDataDataDataDataDataDataDataDataData
displayName: Ted Doe
name: ##userName

我需要导出的格式是:

firstName lastName userName
firstName lastName userName
firstName lastName userName

空格是制表符,因此我可以将该文件导入数据库。我有在 VBScript 中执行此操作的经验,但我正在尝试切换到使用 Perl 来尽可能多地进行服务器管理。

我不确定我想要什么的语法基本上是

while not endoffile{
detect "displayName: " & $firstName & " " & $lastName
detect "name: ##" & $userName

write $firstName tab $lastName tab $userName to file
}

另外,如果有人能向我指出一个专门针对 Perl 使用的文本解析语法的资源,我将不胜感激。我遇到的大多数资源都不是很有帮助。

另外,一些用户名是数字。前两个数字仍需要修剪,但如果有帮助,用户名的长度始终为 6 个字符。

【问题讨论】:

  • 值得注意的是,从单个字符串中解析出名字和姓氏字段并非易事。考虑Sarah Michelle GellarFarrah Fawcett Majors 的情况。一个正确的解析器(有可能)会知道解析这些名字的正确方法是“Sarah Michelle”、“Gellar”和“Farah”、“Fawcett Majors”。你将如何处理这些边缘情况取决于你,但你应该确保有一个指定的行为。否则,Robert De Niro 和他的朋友会破坏你的软件。

标签: perl parsing text


【解决方案1】:

这样的事情应该可以解决问题——它从标准输入读取并输出到标准输出,因此您可以使用普通的 unix 管道来使用文件:

#!/usr/bin/perl

use strict;
use warnings;
use String::Util 'trim';

# set "line ending" to \n\n, to allow slurping by paragraphs:
local $/ = "\n\n";

while (my $line = <>)
{
    chomp $line;

    my ($displayName) = ($line =~ /^displayName: (.+)$/m);
    my ($name) = ($line =~ /^name: ##(.+)$/m);
    trim $displayName;
    trim $name;

    my ($firstName, $lastName) = ($displayName =~ /^([^ ]+) (.+)$/);

    print "$firstName\t$lastName\t$name\n";
}

我使用您在下面提供的示例输入(test.pl &lt; input.txt)对此进行了测试,并得到了输出:

John Doe 用户名 Jane Doe 用户名 泰德·多伊用户名

您可以在 $/ 下的 perldoc perlvar 或此 SO 问题(需要链接)中阅读有关在段落模式下啜饮的信息。使用匹配运算符上的 m 标志启用多行内的匹配 -- 参见 perldoc perlre

【讨论】:

  • 脚注:我一直无法找到对段落模式的 SO 引用,尽管我知道 $/ 过去曾多次讨论过。如果有人找到此链接,请添加评论或将其编辑到问题中 - 谢谢!
  • 这里有一个关于段落解析的问题:stackoverflow.com/questions/1809469/…
  • @FM:那个人讨论了设置local $/ = undef;——但我相信不久前有一个问题讨论了将其设置为"\n\n"以便一次阅读段落.. .
  • 啊啊啊,段落解析,这就是我应该一直在寻找的。感谢您的回答!
  • 在连接中使用未初始化的值 $firstName 在连接中使用未初始化的值 $lastName 当我尝试这个脚本时,我不断收到这些错误。
【解决方案2】:

这是我的解决方案。

use strict;
use warnings;
my $fh;
my $file_contents;
my @info;
open $fh, '<', "data" or die($!);
local $/ = undef;
$file_contents = <$fh>;

while($file_contents =~ /.ame: (.*?)$(.*?).ame: (.*?)$/smg)
{

   my $displayname = $1;
   my $username = $3;
   $displayname =~ s/^\s+//; #clean off any whitespace from front/back
   $displayname =~ s/\s+$//;
   my ($firstname, $lastname) = split(/\s+/, $displayname); #split on whitespace

   print "$firstname\t$lastname\t$username\n"; #note the tabs
}

【讨论】:

  • 第 8 行没有这样的文件或目录,不太清楚这里发生了什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
  • 2015-04-10
  • 2021-03-04
  • 1970-01-01
  • 2014-11-23
  • 2019-05-09
  • 1970-01-01
相关资源
最近更新 更多