Regex 如何在perl中使用多个模式拆分字符串?

Regex 如何在perl中使用多个模式拆分字符串?,regex,string,perl,split,Regex,String,Perl,Split,我要拆分具有多个模式的字符串: 前 我想要一个输出: 10 10 10 12 1 2011 正确的方法是什么?在regex分隔符中使用a来匹配一组可能的分隔符 my $string= "10:10:10, 12/1/2011"; my @string = split /[:,\s\/]+/, $string; foreach(@string) { print "$_\n"; } 解释 斜杠对/…/表示要匹配的正则表达式或模式 一对方括号[…]表示正则表达式的字符类 里面是一组可

我要拆分具有多个模式的字符串:

我想要一个输出:

10
10
10
12
 1
2011
正确的方法是什么?

在regex分隔符中使用a来匹配一组可能的分隔符

my $string= "10:10:10, 12/1/2011";
my @string = split /[:,\s\/]+/, $string;

foreach(@string) {
    print "$_\n";
}
解释

  • 斜杠对
    /…/
    表示要匹配的正则表达式或模式

  • 一对方括号
    […]
    表示正则表达式的字符类

  • 里面是一组可能匹配的字符:冒号
    、逗号
    、任何类型的空格字符
    \s
    ,以及前斜杠
    \/
    (反斜杠作为转义字符)

  • 需要使用
    +
    匹配紧靠其前面的一个或多个字符,在本例中,这是整个字符类。如果没有此选项,逗号空间将被视为两个独立的分隔符,从而在结果中增加一个空字符串


如果您想要数字,请提取数字:

my @numbers = $string =~ /\d+/g;
say for @numbers;
不需要捕获括号,如中所述:

/g修饰符指定全局模式匹配——即匹配 在字符串中尽可能多地重复。它的行为取决于 上下文。在列表上下文中,它返回子字符串的列表 由正则表达式中的任何捕获括号匹配如果 没有括号,它返回所有匹配项的列表 字符串,好像整个图案周围都有括号。

错误的工具

my $string = "10:10:10, 12/1/2011";
my @fields = $string =~ /([0-9]+)/g;

当您解析某个显然是日期/时间的对象时,我想知道将其解析为DateTime对象是否更有意义。

回答您最初的问题:
my $string= "10:10:10, 12/1/2011";

my @string = split(m[(?:firstpattern|secondpattern|thirdpattern)+], $string);

my @string = split(m[(?:/| |,|:)+], $string);

print join "\n", @string;
您正在寻找:


但是,正如其他答案所指出的,你可以通过进一步的简化或概括来改进这一点。

你可以在非数字上进行拆分

#!/usr/bin/perl
use strict;
use warnings;
use 5.014;

my $string= "10:10:10, 12/1/2011";
say for split /\D+/, $string;


工作得非常好!谢谢顺便说一句,你介意解释一下这个代码吗/[:,\s\/]+/感谢您的额外输入,这简单地解释了一切!:我知道这是一个旧线程,但我想知道如何将[]()添加到分隔符列表中?当我把[]()添加到那里时,它似乎摆脱了它。@KingsInnerSoul,在每一个前面添加一个反斜杠,就像我在上面的斜杠中所做的那样,
/,;:
最好写成
[/,:]
@TLP,是吗?IIRC替换在内部被编译成一个trie,字符类是吗?不是说你错了,真的是个问题。@JoelBerger我不知道里面的内容,但我认为它更容易理解。这里有一个基准:
perl-我们“使用基准qw(cmpthese);$a=qq(10:10:10,12/1/2011);cmpthese(100000,{Piped=>sub{my@r=split(m[(?:/,|:)+],$a);},Class=>sub my@r=split(m[(?:[/,:/,:)+],$a);});”;“
Piped 142450/s---27%//194 Class=>175/s看起来像是更快的字符类,没有看到m分隔符是括号。奇怪的是它没有抱怨。好吧,使用
m###
,结果会快45%。这个答案更一般——它也可以用于整个单词,我不知道你突出显示的行为,谢谢,对高尔夫也有好处!我不知道我能用这种方法。好主意!非常感谢你@不客气
split
是一个非常好的工具,但我觉得使用统一的分隔符效果最好。在这种情况下,常见的元素是数字,因此更容易使用它们。@TLP是的,实际上我使用了这种方法,但我没有将其标记为答案,只是为了符合原始问题。无论如何,谢谢你的主意。我很高兴能从你喜欢的陌生人那里得到这么好的想法。@quinekxi我的许多答案不是老年退休金计划要求的解决方案,而是我认为他们真正想要的解决方案。您的问题实际上是“如何最好地从这个字符串中提取数字?”这就是您得到的答案。:)是的,我知道,对不起,我不知道还有其他方法。@quinekxi,不需要道歉,你没有做错任何事。一个好的回答通常来自于对全局的考虑。Brad Gilbert:因为这是谷歌给我的第一个,我自己用了5.10,可移植性可能是个问题。我不知道有一个不可知论的版本。谢谢你提供链接。
my $string = "10:10:10, 12/1/2011";

my @string = split(/:|,\s*|\//, $string);

foreach(@string) {
    print "$_\n";
}
#!/usr/bin/perl
use strict;
use warnings;
use 5.014;

my $string= "10:10:10, 12/1/2011";
say for split /\D+/, $string;