Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl-Regex、条件和匹配多个对象以匹配不一致的字符串_Regex_Perl - Fatal编程技术网

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

Perl-Regex、条件和匹配多个对象以匹配不一致的字符串,regex,perl,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

从文本文件中,我将每一行加载到一个变量中(
$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
(如果存在)的变量中。

我一直看到有人试图在单个正则表达式中塞进太多的内容

#!/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;
    }
}
我会这样做

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

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

  • 如果找到捕获,则将捕获分配给
    $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

在liune或shebang命令行上,您应该使用警告“all”而不是
-w
。您还应该使用
chomp
而不是
chop
,并且使用有助于他人而非自己的样式选择,这主要意味着使用@Borodin,将
chop
更改为
chomp
,然而,我不太明白你指的是什么风格的变化。我所看到的唯一一件事是开始的花括号的位置,但这确实是一个品味的问题(我只是讨厌后面的括号),我怀疑这对任何人来说都是一个问题。还有什么吗?这看起来是一个很好的解决方案,重点是在单个正则表达式中塞进太多的内容。谢谢,我也看到了这种趋势。我真的不知道为什么-我的意思是,我想一个'权力'正则表达式似乎相当强大,但它。。。确实做了一些让perl看起来有点糟糕的事情。增加了复杂性,降低了清晰度,但实际上没有获得多少效率,因为它很简洁。@Sobrique,请看一下我编辑的问题,我刚刚发现了一个边缘情况。如果折扣总是这样括起来,适应这个答案应该很简单。@Sobrique我的正则表达式很弱,我今天的大脑很弱,我仍在试图弄清楚上面的工作原理,更不用说适应它:)处理复杂正则表达式的规则1:不要,使用单独的正则表达式。@Sobrique我理解,谢谢
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