5

我有一个包含要解析的 json 对象的文件,类似于这个:

{
"_id" : ObjectId("523a58c1e4b09611f4c58a66"),
"_items" : [
    {
        "adGroupId" : NumberLong(1230610621),
        "keywordId" : NumberLong("5458816773")
    },
    {
        "adGroupId" : NumberLong(1230613681),
        "keywordId" : NumberLong("3204196588")
    },
    {
        "adGroupId" : NumberLong(1230613681),
        "keywordId" : NumberLong("4340421772")
    },
    {
        "adGroupId" : NumberLong(1230615571),
        "keywordId" : NumberLong("10525630645")
    },
    {
        "adGroupId" : NumberLong(1230617641),
        "keywordId" : NumberLong("4178290208")
    }
]}

我想从 de NumberLong() 中获取数字。起初我只需要keywordId,并设法通过以下方式完成它:

cat listado.txt |& perl -ne 'print "$1," if /\"keywordId\" : NumberLong\(\"?(\d*)\"?\)/' keywordIds.txt

这会生成一个带有数字的逗号分隔文件。我现在还需要 de adGroupIds,所以我正在尝试以下匹配的正则表达式,但没有运气:

cat ./work/listado.txt |& perl -ne 'print "$1-$2," if /\"adGroupId\" : NumberLong\(\"?(\d*)\"?\),\s*\"keywordId\" : NumberLong\(\"?(\d*)\"?\)/m'

正则表达式匹配,但我相信 perl 没有做多行,即使我使用的是/m.

有任何想法吗?

4

5 回答 5

6

/m影响什么^$匹配。你都不用,所以/m没有效果。

您一次只能读取一行,因此一次只能匹配一行。/m不可能导致正则表达式与等待从它不知道的某个文件句柄中读取的数据相匹配。

您可以通过使用并循环所有匹配项将整个文件加载到内存中,-0777而不仅仅是抓取第一个匹配项。

于 2013-09-26T20:54:01.037 回答
1

根据数据的确切结构,您可以使用行号:

while (<>) {
  if ( /NumberLong\("?(?<nr>\d+)/ ) {
    $.%2 ? print "$+{nr}-" : print "$+{nr}\n";
  }
}

或使用标志:

my $flag = 0;

while (<>) {
  if ( /NumberLong\("?(?<nr>\d+)/ ) {
    !$flag 
      ? (print "$+{nr}-" and $flag++)
      : (print "$+{nr}\n" and $flag--);
  }
}

或啜饮:

use 5.010;
my $file;

{
  local $/;
  $file = <>;
}

while ($file =~ /adGroupId" : NumberLong\("?(?<first>\d+).+?keywordId" : NumberLong\("?(?<second>\d+)/gs ) {
  say "$+{first}-$+{second}";
}
于 2013-09-26T21:41:52.507 回答
1

这很简单,只需grepand sed

grep adGroupId listado.txt | sed -E  "s/[^0-9]+//g"
  1. 匹配包含adGroupId的行
  2. 删除所有不是数字的东西
于 2013-09-26T20:54:16.940 回答
0

看看File::MultilineGrep

摘自其描述:被视为具有重复结构的文本文件。这些结构具有重复的起始定界符、可选的终止定界符和可变内容。即这些结构的部分或全部字段是可选的。一项任务是选择包含指定模式的所有整体结构。这可以使用多行正则表达式来完成。但是有一个性能问题:使用正则表达式的处理时间与结构的数量不成正比,因此增加这个数量可能会导致正则表达式永远不会完成。提议的函数的处理时间与结构的数量成正比。

于 2014-05-07T02:44:56.873 回答
0
perl -ne "print $1.'-' if /adGroupId.+?(\d+)/;print $1.',' if /keywordId.+?(\d+)/" listado.txt
于 2013-09-27T09:32:10.247 回答