保留字符串的前两部分,并保留它们之间的分隔符

3
有没有更简洁/Perl风格的方法来实现以下功能:
my @components = split /-/, $original;
my $final_string = $components[0]."-".$components[1];  

输入的字符串最多包含2个-,最后一个是可选的。我想保留第一部分。例如,10-9-1应该变成10-9,而输入10-9应该保持不变。


$original=~s/^([^\-]+\-\d+)(.+)$/$1/g; - ssr1012
@ssr1012:那会修改 $original 吗? - Jim
($mynew = $original)=~s/^([^\-]+\-\d+)(.+)$/$1/g; print $mynew; - ssr1012
这不会修改原始值。 - ssr1012
4个回答

5
use Modern::Perl;

my $re = qr/-\d+\K.*$/;
while(<DATA>) {
    chomp;
    s/$re//;
    say;
}
__DATA__
10-9-1
10-9

对于一个字符串:

my $original = '10-9-1';
(my $final = $original) =~ s/-\d+\K.*$//;
say $final;

说明:

s/
    -       # find the first dash in the string
    \d+     # 1 or more digits
    \K      # forget all we have seen until this posiiton
    .*      # rest of the line
    $       # end of line
//

这如何仅捕获最后一部分? - Jim
1
你的代码对于 "3-4-5\n" 无法正常工作。它输出的是 "3-4\n" 而不是 "3-4" - melpomene
1
@melpomene:那只是我的习惯。 - Toto
@Toto 然后它会将 "3-4-\r\n56" 转换为 "3-456" - melpomene
@melpomene:然后,使用/s标志。 - Toto
显示剩余2条评论

4

在这里使用正则表达式匹配会更容易。

my ($final_string) = $original =~ /^([^-]*-[^-]*)/;

如果你想在原地进行更改,可以使用替换操作。
$original =~ s/^[^-]*-[^-]*\K.*//s;

2
$original =~ m/^([^\-]+\-[^\-]+)/ or warn "Unable to match regex in string: $original";
my $final_string = $1;

希望这能回答您的问题。它并不受任何特定字符串的限制 - 比如连字符后面的文本应该是数字或其他什么内容。如果不匹配,它会发出警告。

假设$original变量只有一个要匹配的实例(从问题中推断出来)。


这会修改 $original 吗? - Jim
不会的。它将使用匹配的正则表达式字符串更新$final_string字符串,并保留原始字符串不变。 - Arun
2
请注意:如果模式不匹配,将会把之前在 $1 中的任何内容放入 $final_string 中。 - ikegami

2

您已经获得的正则表达式解决方案可能是最好的方法,但也可以使用 split()join() 来完成。

# You need this to use 'say()'
use feature 'say';

while (<DATA>) {
  chomp;

  say join '-', (split /-/)[0, 1];
}

__DATA__
10-9-1
10-9
(split /-/)[0, 1]将从split()返回的列表中获取前两个元素。

我可以让这段代码工作...但不能让Dave Cross的代码工作。有什么想法吗? while (<FIN>){ chomp; @_ = split(/-/); say join '-', $[0], $[1]; } - M__
1
@MichaelG.:这似乎是我代码的更复杂版本。不确定为什么你把它分成了两个语句。在我看来似乎是不必要的。此外,请不要将@_用于除子程序参数之外的任何其他用途。 - Dave Cross
1
@MichaelG.:我可以让这段代码运行起来 - 你需要给我们更多的信息。你看到了什么意外的行为? - Dave Cross
我没有反对的立场。我无法将此编译(split /-/)[0,1]。我会在下面发布我的未经授权版本。 - M__
1
我已经添加了 use feature 行,这应该可以解决任何编译问题。 - Dave Cross

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接