正则表达式适用于 python 模拟器,但不适用于 perl

nck*_*nck 4 python regex perl

您好,我正在使用在线正则表达式模拟器来测试我所写的内容是否正确:我想从以下文本中提取信息:

Test23242asdsa 800,03 23.05.19 22.05.19
Tdsadas,tsadsa test 1.020,03 23.05.19 22.05.19
Test,23242 0,03 23.05.19 22.05.19
Run Code Online (Sandbox Code Playgroud)

我尝试在 perl 中使用相同的代码:

use strict;
my $entry = 'Test23242asdsa 0,03 23.05.19 22.05.19';
my ($name, $expense, $date_expense, $date_paid) = $1, $2, $3, $4 if ($entry =~ m/^(.+)\s((?:\d+\.)?\d{1,3},\d{2})\s(\d{2}\.\d{2}\.\d{2})\s(\d{2}\.\d{2}\.\d{2})$/);
print "Name: '$name', Expense: '$expense', Date: '$date_expense', Date Paid: '$date_paid' \n";
Run Code Online (Sandbox Code Playgroud)

如果我在这里使用相同的正则表达式:

https://regex101.com/
^(.+)\s((?:\d+\.)?\d{1,3},\d{2})\s(\d{2}\.\d{2}\.\d{2})\s(\d{2}\.\d{2}\.\d{2})$
Run Code Online (Sandbox Code Playgroud)

它正确检测 de regex。我虽然 python 和 perl 使用相同的正则表达式语法,所以我不明白发生了什么。

Bar*_*mar 6

正则表达式很好,问题在于您如何设置变量。

$1, $2, $3, $4由于 Perl 的运算符优先级,您需要用括号括起来进行列表赋值。

将其更改为

my ($name, $expense, $date_expense, $date_paid) = ($1, $2, $3, $4) if ($entry =~ m/^(.+)\s((?:\d+\.)?\d{1,3},\d{2})\s(\d{2}\.\d{2}\.\d{2})\s(\d{2}\.\d{2}\.\d{2})$/);
Run Code Online (Sandbox Code Playgroud)

工作演示

  • 关于“*您需要将 $1、$2、$3、$4 包装在列表中才能进行列表分配。*”,您的意思是将它们包装在括号中。括号不创建列表;它们只是超越优先级,这正是这里所需要的。 (5认同)