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), за которым следуют тире и две буквы.
Чтобы объяснить регулярное выражение, ниже приведен расширенный источникс комментариями:
// 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
Четырехзначный номер и трейлинг \-[A-Z]{2}
были (для меня) очевидны.Мой метод для римских цифр состоял в следующем:
- Открыть Excel Заполните столбец 1-33.
- Преобразовать этот столбец в римские цифры (во всех 7 различных вариантах).
- Проверьте, не отличались ли какие-либо из разновидностей от 1-33 (они не были).
- Возились с перемещением римских цифр в минимальное количество уникальных узоров, ограничивающее их до 33 (то есть «тогда будешь считать до тридцати трех, не больше, не меньше. Тридцать три будет числом, которое ты считаешь, и число отсчетов должно быть тридцать три. Тридцать четыре ты не считаешь, нисосчитайте тридцать два, за исключением того, что вы затем переходите к тридцати трем. Тридцать пять прямо сейчас. ")
- Понял, что до тридцати девяти - это единый шаблон (
^(([X]{0,3}([I]([XV]?|[I]{0,2})?|([V][I]{0,3})?)))$
, измененный на захватгруппы для лучшей наглядности). - Изменен шаблон для разрешения до двадцати девяти.
- Добавлен другой, чтобы разрешить от тридцати до тридцати девяти.
- Создайте весь шаблон и протестируйтев RegexBuddy(бесценный инструмент для этого материала) против цифр 0 - 20 000 и римских цифр 1 - 150, за которыми следует «-AA».
- Шаблон сработал, поэтому я разместил его (затем взял еще одну чашку кофе и сам-адобавил «мальчика-атташе» для выполнения того, что я считал прекрасным субботним утренним испытанием).
Под сторонними скобками я предполагаю, что вы имеете в виду группы без захвата (?: ... )
.Я часто использую их для группировки вещей (и группировка здесь совершенно необходима).Я сделал их без захвата, потому что мне не нужно захватывать подгруппы, только родительские группы (и в этом случае использования я не думаю, что их нужно на самом деле захватывать, но это не мешает делать это).Делая их без захвата, они не будут создавать обратных ссылок, что ускоряет обработку (хотя для одного входа выигранное время незначительно).