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