【发布时间】:2021-07-16 14:40:54
【问题描述】:
我尝试在 Debian Liunx 下使用 perl 5.20 将文本或令牌与文本行分开。比如:
RED_123-DASH.DOT: PARAM1 PARAM2 ... MANY MORE
由于\s 分隔的标记后可能有大量参数,我只想要第一个分隔符位置。根据建议的解决方案stack.overflow post form Leon Timmermans和the $-[0] variant,我采用如下代码进行测试:
#!/usr/bin/env perl
# Tokens.pl --- Lead Token Test
use warnings;
use strict;
# Separator pattern for the token
my $TSEP = qr/^\s*[\w\-\.]+(:|\s)/;
# Example text with all ID elements inside
my $TEXT = ' RED_123-DASH.DOT: PARAM1 PARAM2 ...';
# Subroutine for the test
# $text - the text to strip the token from
# $global - use the global flag or not
#
# Output:
# TKN: Token if position found
# SKIP: Original if no position found
sub stripToken($$) {
my ($text, $global) = @_ ;
my $test = 0;
$test = $text =~ /$TSEP/g if $global;
$test = $text =~ /$TSEP/ if not $global;
if ( $test ) {
my $pos = pos($text);
return "SKIP: $text" if not $pos;
return "TKN: ". substr($text, 0, $pos-1);
} else {
return "ORG: $text";
}
}
# Test with global flag OK!
print "WITH.GFLAG: ",stripToken($TEXT, 1), "\n";
# Test without global flag NOT OK!
print "NONE.GFLAG: ",stripToken($TEXT, 0), "\n";
如果您只想要第一个匹配位置,Leon 提出了一个不带/.../g 标志的match_positions 子例程。
https://stackoverflow.com/a/87410/3338646
sub match_positions {
my ($regex, $string) = @_;
return if not $string =~ /($regex)/; # <----------- pos without /.../
return (pos($string) - length $1, pos($string));
}
sub all_match_positions {
my ($regex, $string) = @_;
my @ret;
while ($string =~ /($regex)/g) { # <----------- pos with /.../
push @ret, [pos($string) - length $1, pos($string)];
}
return @ret
}
但这不起作用。
/usr/bin/env perl "Tokens.pl"
WITH.GFLAG: TKN: RED_123-DASH.DOT
NONE.GFLAG: SKIP: RED_123-DASH.DOT: PARAM1 PARAM2 ...
唯一的变体适用于/.../g 标志。
/.../ 表达式有什么问题?
【问题讨论】:
-
“这不起作用”是什么意思?您是否期望
/g和没有/g的结果相同?pos仅适用于/g,但由于您没有告诉我们您要做什么,我无法确定这是否是您的问题。 -
@Dada Leon 避免 /.../g 标志进行第一个位置测试(请参阅编辑)并获得这些位置,在我的代码中这不起作用。如您所见,由于 $pos 为零并返回“SKIP”文本,因此例行程序会跳过。参考子程序中的
....if $global和... if not $global和stripToken(...,1)和stripToken(...,0)进行测试。 -
我不明白你在说什么。此外,您还没有解释您要做什么。如果代码适用于
/g,为什么你想要一个没有/g的版本?如果你想要一个没有/g的版本,你为什么要尝试使用pos,即使它不可能工作? -
@Dada 我不明白你在评论什么..请参阅标题、第一个分隔符位置方面以及 Leon 提出的解决方案。