3

我正在尝试从下面的字符串中提取日期、月份和年份。

my $test_str = "Jan 01, 2004    Feb 01, 2004    Mar 01, 2004    Apr 01, 2004    May 01, 2004";
foreach $s (split('\t', $test_str)) {
   my ($m, $d, $y) = split('[\s|,\s]');
   print ("$m=$d=$y\n");
}

当我打印输出时, $y 总是空的。难道我做错了什么?我的正则表达式是

[\s|,\s] # match a space or space and a comma
4

5 回答 5

4

您的split正则表达式[\s|,\s]是一个字符类(由[]方括号表示),这意味着:“拆分为单个字符,即空格、管道|、逗号或空格(再次)”。您将字符串拆分Jan 01, 2004为四个字符串:

"Jan"
"01"
""        # comma + whitespace creates empty string
"2004"

您还拆分了$_变量,但我认为这是一个错字。

要解决您的问题,请将该行更改为:

my ($m, $d, $y) = split(/[\s,]+/, $s);

如您所见,+量词的使用将去除多个连续的逗号或空格。

于 2012-12-17T15:31:17.020 回答
2

你也可以这样做:split /,?\s/, $s;.

于 2012-12-17T15:58:00.120 回答
1

使用 strict 和 warnings,你会发现这$s会导致编译错误。

然后

my ($m, $d, $y) = split('\s|,\s', $s );

我刚刚摆脱了[]括号,它工作得很好。

于 2012-12-17T15:31:07.317 回答
0

split在这种情况下,只需在目标字符串中查找所有字母数字子字符串,而不是使用,它会更简单。该\w模式匹配字母数字加上下划线字符,并且对于此目的足够准确。

use strict;
use warnings;

my $test_str = "Jan 01, 2004\tFeb 01, 2004\tMar 01, 2004\tApr 01, 2004\tMay 01, 2004";

foreach (split /\t/, $test_str) {
   my ($m, $d, $y) = /\w+/g;
   print "$m=$d=$y\n";
}

输出

Jan=01=2004
Feb=01=2004
Mar=01=2004
Apr=01=2004
May=01=2004
于 2012-12-17T21:47:55.513 回答
0

尝试:

my $test_str = "Jan 01, 2004    Feb 01, 2004    Mar 01, 2004    Apr 01, 2004    May 01, 2004";
foreach my $s (split(/\t/, $test_str)) {
   my ($m, $d, $y) = split(/\s|,\s/,$s);
   print ("$m=$d=$y\n");
}

这给出了你想要的输出:

Jan=01=2004
Feb=01=2004
Mar=01=2004
Apr=01=2004
May=01=2004

正如其他回答的人所提到的,[\s|,\s]是一个与\s, |, or中的一个完全匹配的字符类,(这显然不是你想要的)。

于 2012-12-17T15:31:23.580 回答