1

整数値を1000個に分割する小さな正規表現があり、それがどのように機能するのか疑問に思っていました.

ここにパールコードがあります。

$intval = 10000;
$intval =~ s/([+-]?\d)(?=(\d{3})+(?!\d))/$1,/go;
print $intval;
4

2 に答える 2

6

(...)$1通常の括弧のセットは、特殊変数、$2などを使用して、正規表現が一致した後に参照できるキャプチャ グループです。

[+-]?ブラケットは文字グループを作成します。これは、「これらの文字のいずれかに一致する」ことを意味します。 ?「0回または1回一致する」ことを意味します。したがって、これにより、マッチの開始時に単一の + または - の可能性が考慮されます。

\d1 桁に一致します。

(?=...)これは先読みです。パターンに含まれるすべてが一致する必要がありますが、これを出力の「一致」に含めないでください。また、文字列内の位置を前方に移動することもありません (これは、先読みを使用すると一致が重複する可能性があることを意味します)。

(\d{3})+3 桁の 1 つ以上のグループに一致します。

(?!\d)一致したものの後に別の数字を続けることはできません。

/$1,/一致したもの (一致の一部としてカウントされないため、これには先読み部分が含まれないことに注意してください) を最初のキャプチャ グループに置き換え、その後にコンマを付けます。

goこれらのフラグは、正規表現の動作を設定するオプションです。

  • gif がすべての一致を見つけて置換するまで繰り返すことを意味します。
  • oはインタプリタにパターンを 1 回だけコンパイルするように指示する最適化ですが、パターンには何も補間されないため、ほとんどが時代遅れであり、この場合はまったく違いがありません。

したがって、この正規表現は、1 つの数字の後に 3 の倍数の数字が続き、その数字の後にカンマが続くものに置き換えます。繰り返し実行され、すべての一致が検索されます。これの効果は、カンマを千区切り記号として挿入することです。

1 つ問題[+-]?があります。パーツはまったく不要です。正規表現には数字の前に何が来るかについての要件がないため、+ または - を含む数字は、この部分が削除されても問題なく機能します。

于 2013-01-31T11:42:54.880 に答える
5

そのような疑いがあるときはいつでも、簡単な方法でYape::Regex::Explainを使用してください

#!perl -w
use strict;
use YAPE::Regex::Explain;

print YAPE::Regex::Explain->new(qr/([+-]?\d)(?=(\d{3})+(?!\d))/)->explain();

これが得られます

The regular expression:

(?-imsx:([+-]?\d)(?=(\d{3})+(?!\d)))

matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    [+-]?                    any character of: '+', '-' (optional
                             (matching the most amount possible))
----------------------------------------------------------------------
    \d                       digits (0-9)
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (                        group and capture to \2 (1 or more times
                             (matching the most amount possible)):
----------------------------------------------------------------------
      \d{3}                    digits (0-9) (3 times)
----------------------------------------------------------------------
    )+                       end of \2 (NOTE: because you are using a
                             quantifier on this capture, only the
                             LAST repetition of the captured pattern
                             will be stored in \2)
----------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
----------------------------------------------------------------------
      \d                       digits (0-9)
----------------------------------------------------------------------
    )                        end of look-ahead
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------
  1. 修飾子は、このgパターン マッチをグローバルに行う必要があることを示します
  2. 修飾子は、このoパターンを一度コンパイルする必要があることを指定します

正規表現修飾子の詳細については、perlre修飾子を確認してください

于 2013-01-31T12:32:33.720 に答える