如何在 perl 中将字符串的字母和数字分开?

How to split letter and digit apart of a string in perl?

使用 split() 拆分字符串并从该字符串创建一个数组,使单词和数字分开。

我知道前瞻和后视需要用于零宽度分割,所以我使用了它。

$string = 'A1BB22CCC333DDDD';
@string = split(/(?=\d+)|(?<=\d+)/,$string);
print "@string";

期望:

A 1 BB 22 CCC 333 DDDD

但结果:

Variable length lookbehind not implemented in regex m/(?=\d+)|(?<=\d+)/ at jdoodle.pl line 2.

Command exited with non-zero status 255.

您可以使用 /(\d+)/ 这样的模式来拆分字符串。

该模式包含一个捕获组;如 perldoc split 中所述:

If the PATTERN contains capturing groups, then for each separator, an additional field is produced for each substring captured by a group (in the order in which the groups are specified, as per backreferences);

考虑:

use strict;
use warnings;
my $string = "A1BB22CCC333DDDD";
my @result = split /(\d+)/, $string;
print "$_\n" for @result;

产量:

A
1
BB
22
CCC
333
DDDD

如果字符串确实以数字开头,上述解决方案将 return 一个前导空元素。为避免这种情况,您可以按如下方式调整表达式:

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;