假设我有一个字符串如下:
my $line="(l_extendedprice*(1-l_discount)*(1+l_tax))";
我希望在获得非单词字符时拆分此字符串,并且我还想记住该字符。这是我的代码:
my @split_on_non_word=split /(\W)/,$line;
print scalar @split_on_non_word, "\n";
print "split:$_\n" for @split_on_non_word;
以下是我的输出:
20
split:
split:(
split:l_extendedprice
split:*
split:
split:(
split:1
split:-
split:l_discount
split:)
split:
split:*
split:
split:(
split:1
split:+
split:l_tax
split:)
split:
split:)
问题是,我在我的数组中获得了无效的字符,例如(,*。我感觉它可能与元字符有关。但是,当分裂时,它不会插入任何空字符" +"这也是一个元字符。在这方面有任何帮助非常感谢。
当然,有一些方法来处理数组并摆脱空字符,这是我现在的解决方法。但是,我只是在寻找更好的解决方案。
预期输出:
15
split:(
split:l_extendedprice
split:*
split:(
split:1
split:-
split:l_discount
split:)
split:*
split:(
split:1
split:+
split:l_tax
split:)
split:)
答案 0 :(得分:7)
split()
可能不是获得预期结果的最佳方式,您可以使用正则表达式,
use Data::Dumper;
my $line="(l_extendedprice*(1-l_discount)*(1+l_tax))";
my @split_on_non_word = $line =~ /(\w+|\W)/g;
print Dumper \@split_on_non_word;
输出
$VAR1 = [
'(',
'l_extendedprice',
'*',
'(',
'1',
'-',
'l_discount',
')',
'*',
'(',
'1',
'+',
'l_tax',
')',
')'
];
答案 1 :(得分:3)
另一种方式:
以分割模式捕获的内容很少与某些任务完全相同。如果没有,您要么必须对结果进行后处理,要么使用匹配而不是拆分,要么尝试使用非捕获拆分模式来执行您想要的操作。其他答案采用前两种方法之一。对于第三个,你想要在任何一方都有非单词字符的地方进行拆分,这很容易:
split /(?<=\W)|(?=\W)/
答案 2 :(得分:2)
您已将每个\W
字符声明为字段分隔符。字符串的第一个字符是(
。这意味着它必须将空字符串与后面的字符串分开。
然后你有*(
:两个分隔符的序列。这意味着,它们之间必须有一个空字段。
对于1+l_tax
,显然,分隔符的任意一侧都有非空字符串+
。
对我来说,过滤掉空字段似乎最简单:
#!/usr/bin/env perl
use strict;
use warnings;
use YAML::XS;
my $line = "(l_extendedprice*(1-l_discount)*(1+l_tax))";
my $tokens = [ grep length, (split /(\W)/, $line) ];
print scalar @$tokens, "\n";
print Dump $tokens;
输出:
15
---
- (
- l_extendedprice
- '*'
- (
- '1'
- '-'
- l_discount
- )
- '*'
- (
- '1'
- +
- l_tax
- )
- )
答案 3 :(得分:1)
您可以将单词边界\b
与\W
的检查结合起来,在这种情况下,您可以拆分空字符串,只需将字符串转换为字符列表。
my $line="(l_extendedprice*(1-l_discount)*(1+l_tax))";
my @split_on_non_word = map { /\W/ ? split '', $_ : $_ } split /\b/,$line;
print scalar @split_on_non_word, "\n";
print "split:$_\n" for @split_on_non_word;
输出:
15
split:(
split:l_extendedprice
split:*
split:(
split:1
split:-
split:l_discount
split:)
split:*
split:(
split:1
split:+
split:l_tax
split:)
split:)