我正在尝试在perl中传输文件并对行进行标记并包含标记。
我有:
while( $line =~ /([\/][\d]*[%].*?[%][\d]*[\/]|[^\s]+|[\s]+)/g ) {
my $word = $1;
#...
}
但是当令牌中没有空格时它不起作用。
例如,如果我的行是:
$line = '/15%one (1)(2)%15/ is a /%good (1)%/ +/%number(2)%/.'
我想把这一行分成:
$output =
[
'/15%one (1)(2)%15/',
' ',
'is',
' ',
'a',
'/%good (1)%/',
' ',
'+',
'/%number(2)%/',
'.'
]
这样做的最佳方式是什么?
答案 0 :(得分:2)
(?:(?!STRING).)*
是STRING
,[^CHAR]*
是CHAR
,所以
my @tokens;
push @tokens, $1
while $line =~ m{
\G
( \s+
| ([\/])([0-9]*)%
(?: (?! %\3\2 ). )*
%\3\2
| (?: (?! [\/][0-9]*% )\S )+
)
}sxg;
但这不会验证。如果要验证,可以使用
my @tokens;
push @tokens, $1
while $line =~ m{
\G
( \s+
| ([\/])([0-9]*)%
(?: (?! %\3\2 ). )*
%\3\2
| (?: (?! [\/][0-9]*% )\S )+
| \z (*COMMIT) (*FAIL)
| (?{ die "Syntax error" })
)
}sxg;
以下内容也经过验证,但它更具可读性,可以轻松区分令牌类型。:
my @tokens;
for ($line) {
m{\G ( \s+ ) }sxgc
&& do { push @tokens, $1; redo };
m{\G ( ([\/])([0-9]*)% (?: (?! %\3\2 ). )* %\3\2 ) }sxgc
&& do { push @tokens, $1; redo };
m{\G ( (?: (?! [\/][0-9]*% )\S )+ ) }sxgc
&& do { push @tokens, $1; redo };
m{\G \z }sxgc
&& last;
die "Syntax error";
}
pos
将为您提供有关错误发生位置的信息。