4

ユーザーが入力したかどうかを確認する正規表現を作成する必要があります。

  • 4桁または
  • XXXXXX-YYのような値。ここで、XはIからXXXIIIまでのローマ数字で、YYは2つのラテン文字(AZ)です。
4

3 に答える 3

3

要件に応じて、これらは可能なローマ数字形式です。読みやすくするために、Xの最大数のみが示されています。

XXX III     (or: <empty>, I or II instead of III)
XX V       (or: IV, IX and X instead of IV)

私はこのコンパクトなパターンを提案します:

/^(\d{4}|(?=[IVX])(X{0,3}I{0,3}|X{0,2}VI{0,3}|X{0,2}I?[VX])-[A-Z]{2})$/i

説明:

^                Begin of string
(                Begin of group 1.
  \d{4}             4 digits

|                 OR

  (?=[IVX])         Look-ahead: Must be followed by a I, V or X
  (                  Begin of group 2.
     X{0,3}I{0,3}       = 0 1 2 3  + { 0 ; 10 ; 20 ; 30} (roman)
  |                  OR
     X{0,2}VI{0,3}      = 5 6 7 8  + { 0 ; 10 ; 20 }     (roman)
  |                  OR
     X{0,2}I?[VX]       = 4 9      + { 0 ; 10 ; 20 }     (roman)
  )                  End of group 2
  -[A-Z]{2}          Postfixed by a hyphen and two letters
)                 End of group 1.
$                End of string
于 2012-02-18T13:49:05.890 に答える
2

さて、IとXXXIIIの間のローマ数字に一致する部分は次のとおりです。

(?:X(?:X(?:V(?:I(?:I?I)?)?|X(?:I(?:I?I)?)?|I(?:[VX]|I?I)?)?|V(?:I(?:I?I)?)?|I(?:[VX]|I?I)?)?|V(?:I(?:I?I)?)?|I(?:[VX]|I?I)?)

これによって明らかにされたように:

#!/usr/bin/env perl
use Regexp::Assemble;
use Roman;

my $ra = new Regexp::Assemble;

for my $num (1..33) {
    $ra->add(Roman($num));
} 

print $ra->re, "\n";
于 2012-02-18T12:27:25.647 に答える
1
function inputIsValid(value) {
    var r = /(^[0-9]{4}$)|(^(?:(?:[X]{0,2}(?:[I](?:[XV]?|[I]{0,2})?|(?:[V][I]{0,3})?))|(?:[X]{3}[I]{0,3}))\-[A-Z]{2}$)/ig;
    return value.match(r);
}

これは、4桁の入力、またはローマ数字(1〜33の範囲)の後にダッシュと2文字が続くいずれかに一致します。

正規表現を説明するために、以下はコメント付きの拡張ソースです。

// Test for a 4-digit number
(                                       // Start required capturing group
    ^                                   // Start of string
    [0-9]{4}                            // Test for 0-9, exactly 4 times
    $                                   // End of string
)                                       // End required capturing group
|                                       // OR
// Test for Roman Numerals, 1 - 33, followed by a dash and two letters
(                                       // Start required capturing group
    ^                                   // Start of string
    (?:                                 // Start required non-capturing group
        // Test for 1 - 29
        (?:                             // Start required non-capturing group
            // Test for 10, 20, (and implied 0, although the Romans did not have a digit, or mathematical concept, for 0)
            [X]{0,2}                    // X, optionally up to 2 times
            (?:                         // Start required non-capturing group
                // Test for 1 - 4, and 9
                [I]                     // I, exactly once (I = 1)
                (?:                     // Start optional non-capturing group
                    // IV = 4, IX = 9
                    [XV]?               // Optional X or V, exactly once
                    |                   // OR
                    // II = 2, III = 3
                    [I]{0,2}            // Optional I, up to 2 times
                )?                      // End optional non-capturing group
                |                       // OR
                // Test for 5 - 8
                (?:                     // Start optional non-capturing group
                    [V][I]{0,3}         // Required V, followed by optional I, up to 3 times
                )?                      // End optional non-capturing group
            )                           // End required non-capturing group
        )                               // End required non-capturing group
        |                               // OR
        // Test for 30 - 33
        (?:                             // Start required non-capturing group
            // Test for 30
            [X]{3}                      // X exactly 3 times
            // Test for 1 - 3
            [I]{0,3}                    // Optional I, up to 3 times
        )                               // End required non-capturing group
    )                                   // End required non-capturing group
    // Test for dash and two letters
    \-                                  // Literal -, exactly 1 time
    [A-Z]{2}                            // Alphabetic character, exactly 2 times
    $                                   // End of string
)                                       // End required capturing group

4桁の数字と末尾\-[A-Z]{2}は(私には)自明でした。ローマ数字の私の方法は次のとおりでした:

  1. Excelを開く列に1-33を入力します。
  2. その列をローマ数字に変換します(7種類すべて)。
  3. 品種のいずれかが1-33と異なっているかどうかを確認します(そうではありませんでした)。
  4. ローマ数字を33に制限する最小数の固有のパターンに移動することをいじくりまわします(つまり、「それなら、あなたは33に数えなければなりません、それ以上でもそれ以下でもありません。33はあなたが数えなければならない数であり、数え方の数は三十三である。三十四は数えない。また三十二を数えない。ただし、三十三に進むことを除いて。三十五は正解である。」)
  5. 最大39個が単一のパターンであることに気づきました(^(([X]{0,3}([I]([XV]?|[I]{0,2})?|([V][I]{0,3})?)))$より明確にするためにグループをキャプチャするように変更されました)。
  6. 最大29を許可するようにパターンを変更しました。
  7. 30から39を許可するために別のものを追加しました。
  8. パターン全体を構築し、RegexBuddy(このようなものにとって非常に貴重なツール)で、0〜20,000の数字と1〜150のローマ数字の後に「-AA」を付けてテストします。
  9. パターンがうまくいったので、私はそれを投稿しました(それから、私が素敵な土曜日の朝の挑戦だと思ったことを完了するために、コーヒーをもう一杯飲み、「アタボーイ」を自己管理しました)。

無関係な括弧とは、キャプチャされていないグループを意味すると思います(?: ... )。私はそれらをグループ化するためによく使用します(そしてここではグループ化が非常に必要です)。サブグループをキャプチャする必要がなく、親グループのみをキャプチャする必要があるため、キャプチャしないようにしました(このユースケースでは、実際にキャプチャする必要はないと思いますが、そうしても問題はありません。 )。それらを非キャプチャにすることにより、処理を高速化する後方参照を作成しません(ただし、単一の入力の場合、得られる時間はごくわずかです)。

于 2012-02-18T12:30:56.920 に答える