Я должен проверить порядковые номера. Для этого мы используем регулярные выражения в C# и определенный продукт, часть порядкового номера является "секундами с полуночи". Существует 86 400 секунд за день, но как я могу проверить его как 5-разрядное число в этой строке?:
654984051-86400-231324
Я не могу использовать это понятие:
[0-8][0-6][0-4][0-0][0-0]
Поскольку затем 86399
не было бы допустимо. Как я могу преодолеть это? Я хочу что-то как:
[00000-86400]
ОБНОВЛЕНИЕ
Я хочу прояснить, что я знаю - и соглашаюсь с - "не используют регулярные выражения, когда существует более простой путь" философская школа. Ответ Jason точно, как я хотел бы сделать это, однако эта проверка порядкового номера для всех порядковых номеров, которые проходят через нашу систему - в настоящее время нет никакого пользовательского кода доступа для этих определенных. В этом случае у меня есть серьезное основание для поиска regex решения.
Конечно, если нет один, то это излагает доводы для пользовательской проверки для этих конкретных бесспорных продуктов, но я хотел исследовать эту авеню полностью прежде, чем идти с решением, которое требует изменений кода.
Создание регулярного выражения для соответствия диапазону произвольных чисел http://utilitymill.com/utility/Regex_For_Range
дает следующее выражение регулярного выражения:
\b0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)\b
Описание вывода:
First, break into equal length ranges:
0 - 9
10 - 99
100 - 999
1000 - 9999
10000 - 86400
Second, break into ranges that yield simple regexes:
0 - 9
10 - 99
100 - 999
1000 - 9999
10000 - 79999
80000 - 85999
86000 - 86399
86400 - 86400
Turn each range into a regex:
[0-9]
[1-9][0-9]
[1-9][0-9]{2}
[1-9][0-9]{3}
[1-7][0-9]{4}
8[0-5][0-9]{3}
86[0-3][0-9]{2}
86400
Collapse adjacent powers of 10:
[0-9]{1,4}
[1-7][0-9]{4}
8[0-5][0-9]{3}
86[0-3][0-9]{2}
86400
Combining the regexes above yields:
0*([0-9]{1,4}|[1-7][0-9]{4}|8[0-5][0-9]{3}|86[0-3][0-9]{2}|86400)
Проверено здесь: http://osteele.com/tools/rework/
Не использовать регулярное выражение? Если вы изо всех сил пытаетесь придумать регулярное выражение для его анализа, в котором говорится, что, возможно, это слишком сложно, и вам следует найти что-то попроще. Я не вижу абсолютно никакой пользы от использования здесь регулярных выражений, когда простой
int value;
if(!Int32.TryParse(s, out value)) {
throw new ArgumentException();
}
if(value < 0 || value > 86400) {
throw new ArgumentOutOfRangeException();
}
будет работать нормально. Это настолько понятно и легко обслуживается.
Не стоит пытаться использовать для этого регулярные выражения, в результате вы получите что-то непонятное, громоздкое и трудное для модификации (кто-то, вероятно, предложит такое :). Что вы хотите сделать, так это сопоставить строку с помощью регулярного выражения, чтобы убедиться, что она содержит цифры в желаемом формате , затем вытащите группу совпадений и проверьте диапазон, используя арифметическое сравнение. Например, в псевдокоде:
match regex /(\d+)-(\d+)-(\d+)/
serial = capture group 2
if serial >= 0 and serial <= 86400 then
// serial is valid
end if
Со стандартной оговоркой «это-не-особая-регулярная-проблема»,
[0-7]\d{4}|8[0-5]\d{3}|86[0-3]\d{2}|86400
Если вам действительно нужно решение с чистым регулярным выражением, я считаю, что это сработает, хотя другие плакаты хорошо замечают, что только проверяют, что они являются цифрами, а затем используют группу соответствия для проверки фактического числа.
([0-7][0-9]{4}) | (8[0-5][0-9]{3}) | (86[0-3][0-9]{2}) | (86400)
I would use regex combined with some .NET code to accomplish this. A pure regex solution isn't going to be easy or efficient to handle large number ranges.
But this will:
Regex myRegex = new Regex(@"\d{9}-(\d{5})-\d{6}");
String value = myRegex.Replace(@"654984051-86400-231324", "$1");
This will grab the value 86400 in this case. And then you'd just check if the captured number is between 0 and 86400 as per Jason's answer.
Я не верю, что это возможно в регулярных выражениях, поскольку это не то, что можно проверить как часть регулярного языка. Другими словами, конечный автомат не может распознать эту строку, поэтому регулярное выражение тоже не может.
Изменить: это можно распознать с помощью регулярного выражения, но не элегантно. Для этого потребуется цепочка монстров или (например: 00000 | 00001 | 00002
или 0 {1,5} | 0 {1,4} 1 | 0 {1, 4} 2
). Для меня необходимость перечисления такого большого набора возможностей проясняет, что, хотя это технически возможно, это неосуществимо или управляемо.