2012-08-11 8 views
12

私はperldoc perlreRegular Expressions Cookbookをスタックしていて、スタックオーバーフローに関する質問をしています。私は現在の一致数をどのように知っていますか?Perlの正規表現が一致した回数を評価する方法はありますか?

(私が正しくドキュメントを理解している場合\g{3})最後に閉じたグループマッチ($^N)の式、マッチ3の内容がありますが、$'$&$`。しかし、私が使うことができる変数は存在しないように見えるだけで、現在のマッチの数が何であるかが分かります。

本当にありませんか?もしそうなら、それが実装するのが難しい理由が説明されているのでしょうか?またはちょうど十分に慎重にperldocを読んでいないのですか?

(${$count++})などのの回避策には、組み込み変数に興味がありますのでご注意ください。

文脈では、一致のあるインスタンスだけに一致する正規表現を作成しようとしています(例えば、すべての文字 "E"の一致に一致しますが、3,7、 10は単に配列内の数字です)。私はthis SO questionへのより慣用的な答えを構築しようとすると、これに遭遇しました。

正規表現を実際に3,7、および10を正規表現自体に挿入する文字列として評価しないようにしたいと思います。

+0

キャプチャしたグループの数ではなく、一致する数が必要です。 – DVK

+0

'私は組み込み変数に興味がありますので注意してください':perldoc perlvarにない場合は存在しますか? perlvarにはすべての* perl組み込み変数が含まれていると仮定しています。 – TLP

+1

このような変数はありません。 perlvarはすべてのビルトイン変数を記述していません - 例えば '@ ISA 'は表示されませんが、すべてはどこかに書かれています。 Perlは隠された機能を持っていない傾向があります。あなたが解決しようとしている問題の例が、あなたが与える参照よりも優れていますか? – Borodin

答えて

5

これで少し遊んだことがあります。もう一度、私はこれが実際にあなたが探しているものではないことを知っていますが、私はそれがあなたがそれを望む方法で存在するとは思わない。

私には2つの考えがありました。まず、セパレータ保持モードを使用するsplitを使用すると、出力リストの奇数番号の要素としてインタースティシャルビットが取得されます。 splitからのリストでは、あなたがオンになっていると、あなたが好きどのように一緒に戻ってそれを置く一致したカウント:

use v5.14; 

$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz'; 

my @bits = split /(\d+)/; # separator retention mode 

my @skips = qw(3 7 10); 
my $s; 
while(my($index, $value) = each @bits) { 
    # shift indices to match number (index = 2 n - 1) 
    if($index % 2 and ! (($index + 1)/2 ~~ @skips)) { 
     $s .= '^'; 
     } 
    else { 
     $s .= $value; 
     } 
    } 

私が手:

ab^cdef^gh3ij^k^lmn^op7qr^stu^vw10xyz 

私は本当に私まで、私のsplit答えを言って思いました第二の考えを持っていた。 stateは置換の中で機能しますか?それがないことが表示されます:

use v5.14; 
$_ = 'ab1cdef2gh3ij4k5lmn6op7qr8stu9vw10xyz'; 
my @skips = qw(3 7 10); 

s/(\d+)/ 
    state $n = 0; 
    $n++; 
    $n ~~ @skips ? $1 : '$' 
    /eg; 

say; 

これは私に与える:

ab$cdef$gh3ij$k$lmn$op7qr$stu$vw10xyz 

を私は魔法の変数が存在する場合でも、あなたはそれよりもはるかに簡単得ることができるとは思いません。

私は試していない第3の考えがありました。 stateがコードアサーション内で動作するのだろうかと思います。それは、しかし、私はどのようにそれらのいずれかを使用して、一致する可能性がありますビットをスキップしなければならない実際には、失敗に失敗することを確認する必要があります。それはおそらくBorodinが擬似コードでさえもあなたにプレッシャーをかけていたと思われる、本当に複雑なようです。

6

私は、これを他の質問に使用する実際の有用性や知恵を完全に無視しています。

私は、彼らは番号が付けマッチのオフセットを保持するため、@-@+はあなたがやりたいかもしれないと思ったが、正規表現エンジンはすでに最後のインデックスがどうなるか知っているように見える:

use v5.14; 

use Data::Printer; 

$_ = 'abc123abc345abc765abc987abc123'; 

my @matches = m/ 
    ([0-9]+) 
    (?{ 
     print 'Matched \$' . $#+ . " group with $^N\n"; 
     say p(@+); 
    }) 
    .*? 
    ([0-9]+) 
    (?{ 
     print 'Matched \$' . $#+ . " group with $^N\n"; 
     say p(@+); 
    }) 
    /x; 

say "Matches: @matches"; 

これは、文字列を与えます$2にまだ一致していなくても、最後のインデックスを2と表示します。

Matched \$2 group with 123 
[ 
    [0] 6, 
    [1] 6, 
    [2] undef 
] 
Matched \$2 group with 345 
[ 
    [0] 12, 
    [1] 6, 
    [2] 12 
] 
Matches: 123 345 

お知らせ1がまだ記入されていないように、最初の頃は、$+[2]は、undefをであること。あなたはそれで何かをすることができるかもしれませんが、おそらくあなたの質問の精神から離れていると思います。あなたが本当に気に入っていれば、最終的に定義されたインデックスの値が@+である結び付いたスカラーを作成することができます。

関連する問題