请从this code解释这两行Perl。
# separate out "," except if within numbers (5,300)
# previous "global" application skips some: A,B,C,D,E > A , B,C , D,E
# first application uses up B so rule can't see B,C
# two-step version here may create extra spaces but these are removed later
# will also space digit,letter or letter,digit forms (redundant with next section)
$text =~ s/([^\p{IsN}])[,]/$1 , /g;
$text =~ s/[,]([^\p{IsN}])/ , $1/g;
答案 0 :(得分:4)
您的代码会进行两次替换。 ubuntu
是替换,s///
标志告诉它全局,基本上替换所有。
两行都使用正则表达式中的\p{}
unicode property character groups。使用/g
,它会检查字符是否为数字。
IsN
它取代了捕获的非数字,空格,逗号和空格。
第二行也是如此,但首先使用逗号。
您可以使用相同的功能将此代码重写为更短,更简洁。 /
( # capture group
[ # character group
^ # not the following characters
\p{IsN} # all characters that are a number
]
)
[,] # followed by a comma
/
是所有没有此属性的字符,这样就无需\P{}
。这可以进一步缩短到[]
。
\PN
答案 1 :(得分:2)
␠,␠
。␠,␠
。嗯,不太好。因为逗号本身是一个非数字字符,所以上面没有准确描述当一行中有两个逗号时会发生什么。
但是,由于A,B
变为A␠␠,␠␠B
,因此效果不佳,所以不值得详细说明。
标记生成器:
my @tokens;
for ($text) {
if (/\G ( (?: [^,\d]++ | \d(?:,\d++)*+ )++ ) /xgc) {
push @tokens, [ TEXT => $1 ];
redo;
}
if (/\G , /xgc) {
push @tokens, [ 'COMMA' ];
redo;
}
if (/\G \z /xgc) {
push @tokens, [ 'EOF' ];
last;
}
die("Internal error\n");
}