0

index()関数を使用しようとしていますが、完全に一致する場合にのみ、文字列内の単語の位置を検索したいと思います。例えば:

私の文字列はSTRING="CATALOG SCATTER CAT CATHARSIS"

そして私の検索文字列はKEY=CAT

index($STRING, $KEY)CATALOGではなく、CATのようなものを言って一致を確認したいと思います。どうすればこれを達成できますか?ドキュメントには

index関数は、別の文字列内の1つの文字列を検索しますが、完全な正規表現パターン一致のワイルドカードのような動作はありません。

それはそれほど単純ではないかもしれないと私に思わせますが、私のperlスキルは限られています:)。私がやろうとしていることをすることは可能ですか?

うまくいけば、私は自分の質問をうまく表現することができました。よろしくお願いします!

4

5 に答える 5

3

どうですか:

my $str = "CATALOG SCATTER CAT CATHARSIS";
my $key = "CAT";
if ($str =~ /\b$key\b/) {
    say "match at char ",$-[0];;
} else {
    say "no match";
}

出力:

match at char 16
于 2012-12-11T12:17:32.247 に答える
3

Perlの正規表現について学ぶ必要があります。Perlは正規表現を発明しませんでしたが、その概念を大幅に拡張しました。実際、他の多くのプログラミング言語は、 Perl正規表現の使用について具体的に話します。

正規表現は特定の単語パターンに一致します。たとえば、文字列内/cat/のシーケンスcatに一致します。

if ( $string =~ /cat/ ) {
    print "String contains the letters 'cat' in a row\n";
}

多くの点で、これは次と同じことを行います。

my $location = index ( $string, "cat" );
if ( $location =! -1 ) {  # index returns -1 when substring isn't found
    print "String contains the letters 'cat' in a row\n";
}

しかし、これらは両方とも一致します。

  • "Don't let the cat out of the bag"
  • "The Sears catalog arrived in the mail"

あなたは最後のものと一致したくありません。だから、あなたはこれを行うことができます:

 my $location = index $string, " cat ";

今、index $string, " cat "単語カタログと一致しません。名探偵コナン!またはそれは?どうですか:

  • "cat and dog it doth rain."

文が「猫」で始まる場合は、問題がないことを確認して言うことができます。

if ( (index ($string, " cat ") != -1) or (index ($string, "cat") = 0) ) {
    print "String contains the letters 'cat' in a row\n";
}

しかし、これらはどうですか?

  • "The word CAT in all uppercase"
  • "Stupid cat"
  • "Cat! Here Cat! Common Cat!":「猫」という単語の後の句読点
  • "Don't let the 'cat' out of the 'bag'":「猫」の周りの引用符

これらの条件をすべて指定するには、数十行かかる場合があります。

でも:

if ( $string =~ /\bcat\b/i ) {
    print "String contains the word 'cat' in it\n";
}

一人一人を指定し、次にいくつかを指定します。これ\bは単語の境界だと言います。これは、スペース、タブ、引用符、行の先頭または末尾である可能性があります。したがって/\bcat\b/、これは単語catであり、ではないことを指定しますcatalog。最後のionは、一致するときに大文字と小文字を無視するように正規表現に指示するため、、、、、、およびその他すべてCatの可能catな組み合わせCATが見つかります。cAt

実際、Perlの正規表現は、Perlをそもそもそのような人気のある言語にした理由です。

幸い、Perlには正規表現に関するチュートリアルが1つではなく、2つ付属しています。

  • perlretut:Perl正規表現チュートリアル
  • perlrequick:Perl正規表現クイックスタート。

お役に立てれば。

于 2012-12-11T13:14:42.633 に答える
2

これは、この問題の(部分的な)解決策ですindex

use warnings;
use strict;

my $test = 'CATALOG SCATTER CAT CATHARSIS';
my $key = 'CAT';

my $k_length = length $key;
my $s_length = (length $test) - $k_length;

my $pos      = -1;
while (($pos = index $test, $key, $pos + 1) > -1) {
  if ($pos > 0) {
    my $prev_char = substr $test, $pos - 1, 1;
    ### print "Previous character: '$prev_char'\n";
    next if $prev_char ge 'A' && $prev_char le 'Z'
         || $prev_char ge 'a' && $prev_char le 'z';
  }
  if ($pos < $s_length) {
    my $next_char = substr $test, $pos + $k_length, 1;
    ### print "Next character: '$next_char'\n";
    next if $next_char ge 'A' && $next_char le 'Z'
         || $next_char ge 'a' && $next_char le 'z';
  }
  print "Word '$key' found at " . $pos + 1 . "th position.\n";
}

indexご覧のとおり、基本的なPerl文字列関数(およびsubstr)のみを使用しているため、ちょっと言葉遣いです。A-Z見つかった部分文字列が実際に単語であるかどうかのチェックは、次の文字と前の文字(存在する場合)をチェックすることによって行われます。それらがいずれかまたはa-z範囲に属している場合、それは単語ではありません。

これらの文字を(lcを使用して)小文字にしてから、単一の文字範囲のみをチェックすることで、少し単純化できます。

my $lc_prev_char = lc( substr $test, $pos - 1, 1 );
next if $lc_prev_char ge 'a' && $lc_prev_char le 'z';

...しかし、繰り返しになりますが、これは非常に小さな改善です(改善があったとしても)。

今これを考慮してください:

my $test = 'CATALOG SCATTER CAT CATHARSIS CAT';
my $key = 'CAT';
while ($test =~ /(?<![A-Za-z])$key(?![A-Za-z])/g) {
  print "Word '$key' found at " . ($-[0] + 1) . "th position.\n";
}

... 以上です!このパターンは、指定された文字列($ test)を文字通りテストし、指定された部分文字列($ key)の前後にA-Za-z範囲の記号がなく、Perl正規表現マジック(特にこの変数)をサポートします。このようなサブストリングの開始位置を簡単に取得できます。

結論:正規表現を使用して正規表現の作業を行います。

于 2012-12-11T12:29:39.977 に答える
1

正規表現を使用すると、検索に単語の境界と個別の文字を含めることができます。その間

my $string = "CATALOG SCATTER CAT CATHARSIS";
index($string, 'CAT');

$string文字が含まれている場合はゼロ以上を返します。次CATのような正規表現

$string =~ /\bCAT\b/;

前後に単語の境界が含まれていないため、falseを返します。(単語の境界は、文字列の先頭または末尾、あるいは単語文字と非単語文字の間のいずれかです。単語文字は、任意の英数字または下線です。)$stringCAT

于 2012-12-11T12:16:41.767 に答える
-1

\E値を使用します。それで :

#!usr/bin/perl

my $string ="Little Tony";
my $check = "Ton";

if($string =~ m/$check\E/g)
{
print "match";
}
else 
{ 
die("No Match"); 
}
于 2012-12-11T11:47:57.850 に答える