Programing

문자열에서 일치하는 수를 계산하는 Perl 단축키가 있습니까?

lottogame 2020. 10. 21. 07:38
반응형

문자열에서 일치하는 수를 계산하는 Perl 단축키가 있습니까?


내가 가지고 있다고 가정합니다.

my $string = "one.two.three.four";

패턴이 일치하는 항목을 찾은 횟수 (3)를 얻으려면 컨텍스트를 어떻게 사용해야합니까? 한 줄짜리로 할 수 있습니까?

나는 이것을 시도했다 :

my ($number) = scalar($string=~/\./gi);

나는 괄호를 괄호로 묶으 $number면 배열 컨텍스트를 강제하고을 사용 scalar하여 카운트를 얻을 것이라고 생각했습니다. 그러나 내가 얻는 것은 1.


그것은 정규식 자체를 스칼라 컨텍스트에 넣습니다. 대신,리스트 문맥에서 정규 표현식을 넣어 (일치의 수를 얻을 수) 넣어 스칼라 문맥으로.

 my $number = () = $string =~ /\./gi;

이것을 설명하는 가장 명확한 방법은 스칼라로의 인스턴트 캐스트를 피하는 것입니다. 먼저 배열에 할당 한 다음 스칼라 컨텍스트에서 해당 배열을 사용합니다. 그것은 기본적으로 = () =관용구가 할 일이지만 (드물게 사용되는) 관용구가 없습니다.

my $string = "one.two.three.four";
my @count = $string =~ /\./g;
print scalar @count;

또한 Perlfaq4를 참조하십시오 .

효율성이 다른 여러 가지 방법이 있습니다. 문자열 내에서 특정 단일 문자 (X)의 개수를 원하는 경우 다음과 같이 tr /// 함수를 사용할 수 있습니다.

$string = "ThisXlineXhasXsomeXx'sXinXit";
$count = ($string =~ tr/X//);
print "There are $count X characters in the string";

단일 캐릭터를 찾고 있다면 괜찮습니다. 그러나 더 큰 문자열 내에서 여러 문자 하위 문자열을 계산하려는 경우 tr ///가 작동하지 않습니다. 당신이 할 수있는 것은 전역 패턴 매치를 둘러싸는 while () 루프를 감싸는 것입니다. 예를 들어 음의 정수를 세어 보겠습니다.

$string = "-9 55 48 -2 23 -76 4 14 -44";
while ($string =~ /-\d+/g) { $count++ }
print "There are $count negative numbers in the string";

다른 버전은 목록 컨텍스트에서 전역 일치를 사용한 다음 결과를 스칼라에 할당하여 일치 수를 생성합니다.

$count = () = $string =~ /-\d+/g;

다음 코드는 한 줄입니까?

print $string =~ s/\./\./g;

이 시도:


my $string = "one.two.three.four";
my ($number) = scalar( @{[ $string=~/\./gi ]} );

3나에게 돌아온다 . 배열에 대한 참조를 생성하면 정규식이 목록 컨텍스트에서 평가되고 @{..}배열 참조가 역 참조됩니다.


정규식에 OR 조건이있는 경우 (예 /(K..K)|(V.AK)/gi:) 생성 된 배열에는 끝에 카운트에 포함되는 정의되지 않은 요소가있을 수 있습니다.

예를 들면 :

my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my $count = () = $seq =~ /$regex/gi;
print "$count\n";

6의 개수 값을 제공합니다.

이 게시물에서 해결책을 찾았습니다. 배열에서 모든 undef를 어떻게 제거합니까?

my $seq = "TSYCSKSNKRCRRKYGDDDDWWRSQYTTYCSCYTGKSGKTKGGDSCDAYYEAYGKSGKTKGGRNNR";
my $regex = '(K..K)|(V.AK)';
my @count = $seq =~ /$regex/gi;
@count = grep defined, @count; 
my $count = scalar @count;
print "$count\n";

그러면 3의 정답이 나옵니다.


또 다른 방법,

my $string = "one.two.three.four";
@s = split /\./,$string;
print scalar @s - 1;

my $count = 0;
my $pos = -1;
while (($pos = index($string, $match, $pos+1)) > -1) {
  $count++;
}

Benchmark로 확인하면 매우 빠릅니다.


Friedo의 방법은 다음과 같습니다 $a = () = $b =~ $c.

But it's possible to simplify this even further to just ($a) = $b =~ $c, like so :

my ($matchcount) = $text =~ s/$findregex/ /gi;

You could thank just wrap this up in a function, getMatchCount(), and not worry about it destroying the passed string.

On the other hand, you can add in a swap, which may be a bit more computation, but does not result in altering the string.

my ($matchcount) = $text =~ s/($findregex)/$1/gi;

참고URL : https://stackoverflow.com/questions/1849329/is-there-a-perl-shortcut-to-count-the-number-of-matches-in-a-string

반응형