4

我继承了一个从某些文件中提取数据的 perl 脚本。整个脚本运行良好,但最近一些工程师已经为某个通常取一个数字的位置输入了多个数字,因此输出并未显示所有预期的内容。

样本输入:

CRXXXX: "Then some text"

CRs XXXX, XXXX, XX, XXX

CRXXX "Some Text"

目前,这个正则表达式语句我已经在 CR 之后提取了数字,但是如果给出第二行示例输入,它会打印"s XXXX, XXXX, XX, XXX"而不是想要的"XXXX XXXX XX XXX"

我对 perl 非常陌生,并且正在努力弄清楚如何更改此正则表达式以处理所有输入。

 $temp_comment =~ s/\s[cC][rR][-\s:;]*([\d])/\n$1/mg;

提前致谢!

布洛克

4

4 回答 4

2

对于示例数据,例如:

my $temp_comment =
'CR1234: "Then some text"
 CRs 2345, 3456, 45, 567
 CR678 "Some Text"';

尝试:

$temp_comment =~ s/(,)|[^\d\n]+/$1?' ':''/semg;

或者,如果您想靠近字符串模板:

$temp_comment =~ s/ ^                 # multi-line mode, line start
                    \s*               # leading blanks?
                    CR                # CR tag
                    \D*               # non-number stuff
                     (                  # start capture group
                      (?:\d+ [,\s]*)+   # find (number, comma, space) groups
                     )                  # end capture group
                    \D*               # skip remaining non-number stuff
                    $                 # multi-line mode, line end
                  /$1/mxg;            # set multi-line mode + regex comments "x" 

但您必须在后续步骤中删除数字组中的逗号。

$temp_comment =~ tr/,//d;             # remove commas in the whole string

或者

$temp_comment =~ s/(?<=\d),(?=\s\d)//g;  # remove commas between numbers '11, 22'

对于“单步”,您必须使用/e修饰符:

$temp_comment =~ s{ ^                 # line start
                    \s*               # leading blanks?
                    CR                # CR tag
                    \D*               # non-number stuff
                    ((?:\d+ [,\s]*)+) # single or group of numbers
                    \D*               # non number stuff
                    $                 # line end
                  }
                  {do{(local$_=$1)=~y/,//d;$_}}mxeg;

根据上面的数据,这将导致:

1234
2345 3456 45 567
678 

但实际上,如果可能, 请使用更简单的两步方法。后一种正则表达式可能是您的继任者的维护噩梦。

于 2012-07-23T19:31:46.513 回答
1

您最好分两步执行此操作:

1)创建你的正则表达式

s/\s[cC][rR][-\s:;]*([\d\ ]+)/\n$1/mg(注意捕获所有数字的新方法,您只捕获上面的第一个数字)

2)然后只需用查找/替换去掉字符串中的逗号。

于 2012-07-23T19:10:29.323 回答
1
my ($v) = /CR[s ]*((?:\d+[\s,]*)*)/ig;
$v =~ s/,//g;
print $v,"\n";
于 2012-07-23T19:19:04.973 回答
1

也许以下内容对您有用:

use Modern::Perl;

say join ' ', (/(\d+)/g) for <DATA>;

__DATA__
CR1234: "Then some text"
CRs 1111, 2222, 33, 444
CR567 "Some Text"

输出:

1234
1111 2222 33 444
567

希望这可以帮助!

于 2012-07-23T19:41:09.883 回答