【问题标题】:Regex match multiple pattern正则表达式匹配多个模式
【发布时间】:2017-10-08 09:28:12
【问题描述】:

下面是我的测试字符串:

Object: TLE-234DSDSDS324-234SDF324ER
  Page location: SDEWRSD3242SD-234/324/234 (1)
    org-chart           Lorem ipsum dolor    consectetur adipiscing          # Colorado
    234DSDSDS324-32-4/2/7-page2 (2) loc log  Apr 18 21:42:49 2017           1
      Page information: 3.32.232.212.23, Error: fatal, Technique: color
        Comments: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. 
      Validation status: Lorem ipsums dolors sits amets, consectetur adipiscing elit
       Positive control-export: Validated
  Page location: SDEWRSD3242SD-SDF/234/324 (5)
    org-chart           Lorem ipsum dolor    consectetur adipiscin          # Arizona
    234DSDSDS324-23-11/1/0-page1 (1) loc log Apr 18 21:42:49 2017           1
      Page information: 3.32.232.212.23, Error: log, Technique: color
        Comments: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
      Validation status: Lorem ipsums dolors sits amets, consectetur adipiscing elit
       Positive control-export: Validated

我需要在“页面位置:”、“对象:”和“评论:”之后捕获字符串

例如:

对象:TLE-234DSDSDS324-234SDF324ER - 第 1 组

页面位置:SDEWRSD3242SD-234/324/234 (1) - 第 2 组

页面位置:SDEWRSD3242SD-SDF/234/324 (5) - 第 3 组

评论:Lorem ipsum dolor sit amet、consectetur adipiscing elit、sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 - 第 4 组

评论:Lorem ipsum dolor sit amet、consectetur adipiscing elit、sed do eiusmod tempor incididunt ut labore et dolore magna aliqua。 - 第 5 组

这是我的regex URL

我能够捕获字符串,但如果重复任何一个字符串,正则表达式将不会捕获。

【问题讨论】:

  • 如果 ie Page location 出现多次,您就会遇到问题,对吗?
  • 是的。 @Jan.. 页面位置和评论
  • 类似这样的东西:regex101.com/r/t15dD8/8?
  • 没错,但如果我在测试字符串中再添加一个页面位置和评论,它就不匹配了?
  • 所有这些都在一个字符串中(还是在单独的行中)——或者,如何将这些数据输入程序? “页面位置:”是独一无二的,所以您总是需要它后面的内容吗?您需要在“页面位置”之后多远捕捉到第一个换行符?这都显示在一个“Object”的“内部”——你的字符串/文件中是否有多个这样的部分?

标签: regex perl


【解决方案1】:

(问题描述见问题下方的cmets。)

数据位于多行字符串中,多个部分以Object: 开头。在每行中都有多行以短语Page location:Comments: 开头。剩下的所有这些都需要被捕获,并由Objects 组织。

与其尝试折磨人的多行“单”正则表达式,不如将字符串分成几行并逐节处理。这样问题就变得非常简单了。

结果存储在hashrefs数组中;每个键都有显示的短语。由于它们在每个部分中可以出现多次,因此它们的值是 arrayrefs(它们后面的内容)。

use warnings;
use strict;
use feature 'say';

my $input_string = '...'; 
my @lines = split /\n/, $input_string;

my $patt = qr/Object|Page location|Comments/;

my @sections;
for (@lines) 
{
    next if not /^\s*($patt):\s*(.*)/;

    push @sections, {}  if $1 eq 'Object';

    push @{ $sections[-1]->{$1} }, $2;
}

foreach my $sec (@sections) {
    foreach my $key (sort keys %$sec) {
        say "$key:";
        say "\t$_" for @{$sec->{$key}};
    }   
}

复制了输入字符串(为简洁起见,上面不显示),输出为

注释: Lorem ipsum dolor sit amet,[...] Lorem ipsum dolor sit amet,[...] 页面位置: SDEWRSD3242SD-234/324/234 (1) SDEWRSD3242SD-SDF/234/324 (5) 目的: TLE-234DSDSDS324-234SDF324ER

几厘米。

一旦找到Object 行,我们就会向@​​987654329@ 添加一个新的hashref。然后将模式的匹配设置为键,并将其行的其余部分添加到其 arrayref 值。这是针对@sections 的当前(最后一个)元素完成的。

如果模式后面没有任何内容,这会添加一个空字符串。禁止添加next if not $2;

注意。打印复杂数据结构的一种简单而常用的方法是通过核心模块Data::Dumper。但也请参阅Data::Dump 以获得更紧凑的打印输出。

【讨论】:

  • 我在这里猜测,但是 OP 是否需要为每个新对象重新开始收集数据?在那种情况下,我会使用一个哈希数组;从一个空哈希开始,捕获到它,直到看到一个新的“对象:”,此时一个新的空匿名哈希被推送到数组中,数据被捕获到其中。完全同意循环是一个比尝试将逻辑压缩到单个正则表达式更好的解决方案!
  • @JoeMcMahon 是的,如果存在多个Object 部分并需要区分,则需要调整。我在 cmets 和答案本身中问了一个问题,并且正在等待:)。使用一个正则表达式的方法假定所有数据都在一个字符串中可用,这并不清楚。我的问题得到了回答,它是“单独的行”,然后读取文件很常见......我也在等待澄清。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多