Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex Perl拆分函数-使用重复字符作为分隔符_Regex_Perl - Fatal编程技术网

Regex Perl拆分函数-使用重复字符作为分隔符

Regex Perl拆分函数-使用重复字符作为分隔符,regex,perl,Regex,Perl,我想使用重复字母作为分隔符拆分字符串,例如, “123aa23a3”应拆分为('123',23a3'),而“123abc4”应保持不变。 所以我试了一下: @s = split /([[:alpha:]])\1+/, '123aaaa23a3'; 但这返回的是'123','a','23a3',这不是我想要的。现在我知道这是因为,'aaaa'中的最后一个'a'被偏执狂捕获,并因此被split()保存。但无论如何,我不能添加像?:这样的内容,因为必须捕获[[:alpha:]以供反向引用。 我怎样才

我想使用重复字母作为分隔符拆分字符串,例如,
“123aa23a3”
应拆分为
('123',23a3')
,而
“123abc4”
应保持不变。
所以我试了一下:

@s = split /([[:alpha:]])\1+/, '123aaaa23a3';
但这返回的是
'123','a','23a3'
,这不是我想要的。现在我知道这是因为,
'aaaa'
中的最后一个
'a'
被偏执狂捕获,并因此被
split()
保存。但无论如何,我不能添加像
?:
这样的内容,因为必须捕获
[[:alpha:]
以供反向引用。
我怎样才能解决这个问题呢?

嗯,这是一个有趣的问题。我的第一个想法是-您的分隔符将始终是奇数,因此您可以丢弃任何奇数数组元素

也许是这样的

my %s = (split (/([[:alpha:]])\1+/, '123aaaa23a3'), '' );
print Dumper \%s;
这将为您提供:

$VAR1 = {
          '23a3' => '',
          '123' => 'a'
        };
因此,您可以通过
提取模式

不幸的是,我通过
%+
选择模式匹配的第二种方法没有特别的帮助(split没有填充regex内容)

但是像这样的事情:

my @delims ='123aaaa23a3' =~ m/(?<delim>[[:alpha:]])\g{delim}+/g; 
print Dumper \%+;

我们首先处理字符串以提取“2个或更多”字符模式,将其设置为Delmiter。然后,我们用非捕获的方法将它们组合成一个正则表达式,这样我们就可以拆分了

一种解决方案是使用原始的
split
调用并丢弃所有其他值。方便的是,
List::Util::pairkeys
是一个将每对值中的第一个保留在其输入列表中的函数:

use List::Util 1.29 qw( pairkeys );

my @vals = pairkeys split /([[:alpha:]])\1+/, '123aaaa23a3';
给予

这个警告来自这样一个事实,
pairkeys
想要一个大小相等的列表。我们可以通过在末尾增加一个值来解决这个问题:

my @vals = pairkeys split( /([[:alpha:]])\1+/, '123aaaa23a3' ), undef;
或者,也许更简洁一点,就是在列表的开头添加额外的值,并使用
pairvalues

use List::Util 1.29 qw( pairvalues );

my @vals = pairvalues undef, split /([[:alpha:]])\1+/, '123aaaa23a3';

在正则表达式中,可以使用延迟执行断言(也称为延迟正则子表达式),
(?{code})
,使“拆分”直接工作:

@s = split /[[:alpha:]](??{"$&+"})/, '123aaaa23a3';
(?{code})
记录在“perlre”手册页面上


请注意,根据“perlvar”手册页面,在程序中的任何位置使用
$&
都会对所有正则表达式匹配造成相当大的性能损失。我从来没有发现这是一个问题,但是YMMV。

我不认为您可以修改正则表达式以避免创建捕获组,但是您可以扔掉
split
返回的列表中所有奇数元素。如果正则表达式有捕获组,则返回的列表也包含匹配/分组的子字符串。您可以使用另一个选项:
my$str='123aaaa23a3'=~s/([[:alpha:]])\1+/~/r;my@s=split/~~/,$str
use List::Util 1.29 qw( pairvalues );

my @vals = pairvalues undef, split /([[:alpha:]])\1+/, '123aaaa23a3';
@s = split /[[:alpha:]](??{"$&+"})/, '123aaaa23a3';