ユーザーが入力したかどうかを確認する正規表現を作成する必要があります。
- 4桁または
- XXXXXX-YYのような値。ここで、XはIからXXXIIIまでのローマ数字で、YYは2つのラテン文字(AZ)です。
ユーザーが入力したかどうかを確認する正規表現を作成する必要があります。
要件に応じて、これらは可能なローマ数字形式です。読みやすくするために、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
さて、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";
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}
は(私には)自明でした。ローマ数字の私の方法は次のとおりでした:
^(([X]{0,3}([I]([XV]?|[I]{0,2})?|([V][I]{0,3})?)))$
より明確にするためにグループをキャプチャするように変更されました)。無関係な括弧とは、キャプチャされていないグループを意味すると思います(?: ... )
。私はそれらをグループ化するためによく使用します(そしてここではグループ化が非常に必要です)。サブグループをキャプチャする必要がなく、親グループのみをキャプチャする必要があるため、キャプチャしないようにしました(このユースケースでは、実際にキャプチャする必要はないと思いますが、そうしても問題はありません。 )。それらを非キャプチャにすることにより、処理を高速化する後方参照を作成しません(ただし、単一の入力の場合、得られる時間はごくわずかです)。