Perl - Regex,条件和匹配不一致字符串的多个对象

时间:2015-12-08 13:25:37

标签: regex perl

从文本文件中我将每一行加载到变量($line)中。每一行都有一般形式,但不一致,例如

[Foo] - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt £34.99
[BARBAR] ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis £255.25
[BAZZ] - deserunt mollit anim id est laborum. - £500

对于每一行,我想要一个字符串

  • 没有方括号
  • 不包含前导空格或非字母数字字符,例如' - '

为了使事情进一步复杂化,我想将价格作为一个不同的变量返回。

以上数据的几个例子:

$var1 = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt';
$var2 = '£99.99';

$var1 = 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis';
$var2 = '£255.25';

$var1 = 'deserunt mollit anim id est laborum';
$var2 = '£500';

我真的不知道从哪里开始(对我来说)一个非常复杂的正则表达式。

编辑,边缘情况......

原来,在文本文件中有一些我的描述没有涵盖的边缘情况,例如:

[BARBAR] ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis £255.25 (5% off)
[BAZZ] - deserunt mollit anim id est laborum. - £500 (%10 less)

理想情况下,我想将值(例如,'减少10%','减5%')存储在名为$discount的变量中(如果存在)。

2 个答案:

答案 0 :(得分:5)

我一直在看到人们试图将过多的东西塞进一个正则表达式的例子

我会这样做

  • 从字符串的开头删除括号中的子字符串后跟任意数量的非单词字符

  • 删除任意数量的非单词字符,后跟价格,并从字符串末尾删除可选的空格,捕获价格

  • 如果找到一个<{p>

  • ,则将捕获分配给$price

单独处理前缀和后缀可以更容易地编写一个清晰的解决方案,如下所示。不幸的是,描述前缀的括号和反斜杠的混乱无法改进,除非您想使用\[ [^][]* \],我认为这不是明显更好

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

while ( <DATA> ) {
    chomp;
    s/ ^ \[ [^\[\]]* \] \W* //x;

    my $price;
    $price = $1 if s/ \W* (£[\d.]+)? \s* \z //x;

    say $_;
    say $price if $price;
}


__DATA__
[Foo] - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt £34.99
[BARBAR] ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis £255.25
[BAZZ] - deserunt mollit anim id est laborum. - £500

输出

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
£34.99
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
£255.25
deserunt mollit anim id est laborum
£500

答案 1 :(得分:1)

#!/usr/bin/env perl -w

use strict;

while (<>)
{
    chomp;
    if (/^\[[^\]]+\]\W+(.*?)(?:\W+(£\d+(?:\.\d{2})?))?$/)
    {
        print "line: $1\n";
        print "price: $2\n" if $2;
    }
}

输出:

line: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
price: £34.99
line: ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis
price: £255.25
line: deserunt mollit anim id est laborum
price: £500