使用split()拆分字符串,并从该字符串中生成一个数组,使单词和数字分开。
我知道前瞻和后视需要用于零宽度分割,所以我用它。
$string = 'A1BB22CCC333DDDD';
@string = split(/(?=\d+)|(?<=\d+)/,$string);
print "@string";
期望:
A 1 BB 22 CCC 333 DDDD
但结果是:
在regex m /(?= \ d +)|(?<= \ d +)/在jdoodle.pl第2行中没有实现可变长度的lookbehind。
命令以非零状态255退出。
你可以使用像/(\d+)/
这样的模式来分割字符串。
该模式包含一个捕获组;如perldoc split所述:
如果PATTERN包含捕获组,则对于每个分隔符,将为组捕获的每个子字符串生成一个附加字段(按照指定组的顺序,根据后向引用);
考虑:
use strict;
use warnings;
my $string = "A1BB22CCC333DDDD";
my @result = split /(\d+)/, $string;
print "$_\n" for @result;
产量:
A
1
BB
22
CCC
333
DDDD
如果字符串以数字开头,则上述解决方案将返回前导空元素。为避免这种情况,您可以按如下方式调整表达式:
my @result = grep length, split /(\d+)/, $string;
选项1:
无需检查分割点每侧有多少位数,因此您可以简单地用\d+
替换\d
以避免出现错误。但是你会注意到你的解决方案的第二个问题:你不只是在数字和非数字之间分裂;你也在两位数之间分裂。固定:
my @parts = split /(?<=\D)(?=\d)|(?<=\d)(?=\D)/, $string;
选项2:
返回传递给split
的模式捕获的文本,为我们提供了使用split
的替代解决方案。
my @parts = grep length, split /(\d+)/, $string;
grep
处理$string
以数字开头的情况。
当你要拆分的东西实际上不是分隔符时,你需要修复split
的输出。这应该告诉你,在这种情况下,split
不是合适的工具。
选项3:
一个简单的正则表达式匹配将在这里做。
my @parts = $string =~ /\d+|\D+/g;