문자열의 양쪽에서 공백을 다듬기위한 펄 호환 정규 표현식이 있습니까?

StackOverflow https://stackoverflow.com/questions/184590

  •  06-07-2019
  •  | 
  •  

문제

한 줄로이 작업을 수행하는 방법이 있습니까?

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

다시 말해, 문자열에서 모든 선행 및 후행 공백을 제거하십시오.

도움이 되었습니까?

해결책

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

또는

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

다른 팁

내 첫 번째 질문은 ... 왜? 나는 단일 레지 렉스 솔루션이 당신이 시작한 regexp보다 더 읽기 쉬운 것을 보지 못했습니다. 그리고 그들은 확실히 빠르지 않습니다.

#!/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 또는 regexes를 찾으십시오. 새로운 결과가 예측과 일치하는지 확인하십시오. 트렌드가 무엇인지 파악하십시오. 성능이 점점 좋아지고, 한계에 접근하거나, 피크에 접근하고, 거절되기 시작합니까?

재밌게 당신은 이것을 제기해야합니다!

나는 최근에 읽었다 12 개의 (!) 다른 트림 구현의 성능을 분석하는 기사.

이 기사는 구체적으로 JavaScript Regex 구현을 사용하지만 Perl Syntax를 사용 하므로이 토론의 apropos라고 생각합니다.

이단에서 논쟁하면서 왜 전혀 그것을합니까? 위의 모든 솔루션은 한 번의 패스에서 문자열의 양쪽에서 흰색과 공백을 트림한다는 점에서 "정확한"이지만, 읽을 수는 없습니다 (아마도 예상 할 수 있습니다. 이 하나). 코드의 청중이 전문가 수준의 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