有没有办法在一行中做到这一点?

$x =~ s/^\s+//;
$x =~ s/\s+$//;

换句话说,从字符串中删除所有前导和尾随空格。

有帮助吗?

解决方案

$x =~ s/^\s+|\s+$//g;

s/^\s+//, s/\s+$// for $x;

其他提示

我的第一个问题是......为什么?我没有看到任何单正则表达式解决方案比你开始使用的正则表达式更具可读性。他们肯定不会那么快。

#!/usr/bin/perl

use strict;
use warnings;

use Benchmark qw(:all);

my $a = 'a' x 1_000;

my @x = (
         "    $a   ",
         "$a   ",
         $a,
         "    $a"
        );

cmpthese(-5,
         {
             single => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/^\s+|\s+$//g;
                 }
             },
             double => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/^\s+//;
                     $x =~ s/\s+$//;
                 }
             },
             trick => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     s/^\s+//, s/\s+$// for $x;
                 }
             },
             capture => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     $x =~ s/\A\s*(.*?)\s*\z/$1/
                 }
             },
             kramercap => sub {
                 for my $s (@x)
                 {
                     my $x = $s;
                     ($x) = $x =~ /^\s*(.*?)\s*$/
                 }
             },
         }
        );

在我的机器上给出结果:

             Rate    single   capture kramercap     trick    double
single     2541/s        --      -12%      -13%      -96%      -96%
capture    2902/s       14%        --       -0%      -95%      -96%
kramercap  2911/s       15%        0%        --      -95%      -96%
trick     60381/s     2276%     1981%     1974%        --       -7%
double    65162/s     2464%     2145%     2138%        8%        --

编辑:runrig是对的,但变化不大。我已经更新了代码以在修改之前复制字符串,这当然会减慢速度。我还考虑了brian d foy在另一个答案中建议使用更长的字符串(虽然一百万看起来像是矫枉过正)。然而,这也表明在你选择技巧风格之前,你要弄清楚你的字符串长度是什么样的 - 使用较短的字符串可以减少技巧的优点。尽管如此,我已经测试了双倍的胜利。它的眼睛仍然更容易。

Tanktalus显示了非常小的字符串的基准,但随着字符串变大,问题变得更糟。在他的代码中,我更改了顶部:

my $a = 'a' x 1_000_000;

my @x = (
  "   $a   ",
  "$a    ",
  $a,
  "    $a"
  );

我得到了这些结果:

          Rate  single capture   trick  double
single  2.09/s      --    -12%    -98%    -98%
capture 2.37/s     13%      --    -98%    -98%
trick   96.0/s   4491%   3948%      --     -0%
double  96.4/s   4512%   3967%      0%      --

随着字符串变大,使用“技巧”和“双重”几乎是相同的,并且是大多数人所采用的共同解决方案,即“单一”。 (包括我,因为即使我知道这一点,我也无法打破这种习惯),真的开始吮吸。

每当你看一个基准时,想一想它告诉你什么。要查看您是否理解,请更改数据并重试。使数组变长,标量变大,依此类推。使循环,greps或正则表达式在开始,中间和结束时找到东西。查看新结果是否与您的预测相符。弄清楚趋势是什么。性能是否越来越好,达到极限,达到峰值然后开始下降,还是其他什么?

有趣的是你应该提起这件事!

我最近阅读了一篇分析十二(!)种不同修剪实施表现的文章

虽然本文专门使用JavaScript正则表达式实现,但它使用Perl语法,所以我认为它适用于此讨论。

从异端人士那里争论,为什么要这样呢?所有上述解决方案都是“正确的”。因为它们在一次通过中从字符串的两边修剪空白,但没有一个是非常可读的(期望可能这一个)。除非您的代码的受众由专家级别的Perl编码员组成,否则上述候选人中的每一位都应该有一个评论来描述他们的行为(无论如何都可能是一个好主意)。相比之下,这两条线在不使用前瞻,通配符,中间体或任何对于经验适中的程序员来说不是很明显的事情的情况下完成了同样的事情:

$string =~ s/^\s+//;
$string =~ s/\s+$//;

(可以说)性能受到了打击,但只要你不关心执行时的几微秒,增加的可读性就值得。 IMHO。

在这里: $ x = ~s / \ A \ s *(。*?)\ s * \ z / $ 1 /;

$ x = ~s /(^ \ s +)|(\ s + $)// g;

我通常这样做:

($foo) = $foo =~ /^\s*(.*?)\s*$/;

前导空格和尾随空格之间的所有内容都被分组并返回,因此我可以将它分配给相同的旧变量。

或者这个: s / \ A \ s * | \ s * \ Z // g

s/^\s*(\S*\S)\s*$/$1/
$var1 =~ s/(^\s*)(.*?)(\s*$)+/$2/;
$x =~ s/^\s*(.*?)\s*$/$1/;
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top