Многие объяснения уже присутствуют, чтобы объяснить, как это происходит и как это исправить, но вы также должны следовать рекомендациям, чтобы избежать NullPointerException
вообще.
См. также: A хороший список лучших практик
Я бы добавил, очень важно, хорошо использовать модификатор final
. Использование "окончательной" модификатор, когда это применимо в Java
Сводка:
final
для обеспечения хорошей инициализации. @NotNull
и @Nullable
if("knownObject".equals(unknownObject)
valueOf()
поверх toString (). StringUtils
StringUtils.isEmpty(null)
. Вы, кажется, неправильно поняли, как работает определение классов символов в regex.
Чтобы соответствовать любой из строк 01
, 02
, 03
, 04
, 05
, 06
, 07
, 08
, 09
, 10
, 11
или 12
, что-то вроде этого работает:
0[1-9]|1[0-2]
Класс символов сам по себе пытается сопоставить один и ровно один символ из входной строки. [01-12]
на самом деле определяет [012]
, класс символов, который соответствует одному символу от ввода против любого из трех символов 0
, 1
или 2
.
Диапазон -
определение от 1
до 1
, которое включает только 1
. С другой стороны, что-то вроде [1-9]
включает в себя 1
, 2
, 3
, 4
, 5
, 6
, 7
, 8
, 9
.
Начинающие часто делают ошибки определения таких вещей, как [this|that]
. Это не «работает». Это определение символа определяет [this|a]
, то есть оно соответствует одному символу ввода от любого из 6 символов в t
, h
, i
, s
, |
или a
. [29]
Итак, теперь очевидно, что такой шаблон, как between [24-48] hours
, не работает, , Класс символов в этом случае эквивалентен [248]
.
То есть, -
в определении класса символов не определяет числовой диапазон в шаблоне. Двигатели Regex на самом деле не «понимают» числа в шаблоне, за исключением синтаксиса конечного повторения (например, a{3,5}
соответствует между 3 и 5 a
).
Определение диапазона вместо этого использует ASCII / Unicode кодирование символов для определения диапазонов. Символ 0
закодирован в ASCII как десятичный 48; 9
равно 57. Таким образом, определение символа [0-9]
включает в себя весь символ, значения которого находятся между десятичными значениями 48 и 57 в кодировке. Скорее разумно, по дизайну это символы 0
, 1
, ..., 9
.
Давайте посмотрим на другое определение общего символьного класса [a-zA-Z]
В ASCII:
A
= 65, Z
= 90 a
= 97, z
= 122 Это означает, что:
[a-zA-Z]
и [A-Za-z]
эквивалентны [a-Z]
, скорее всего, является незаконным диапазоном символов, поскольку a
(97) «больше чем», чем Z
(90) [A-z]
является законным, но также включает в себя эти шесть символов: [
(91), \
(92 ) ]
(93), ^
(94), _
(95), `` `(96) []
s в регулярном выражении обозначают класс символов. Если диапазоны не заданы, это неявно или s каждый символ внутри него вместе. Таким образом, [abcde]
совпадает с (a|b|c|d|e)
, за исключением того, что он ничего не фиксирует; он будет соответствовать любому из a
, b
, c
, d
или e
. Весь диапазон указывает набор символов ; [ac-eg]
говорит, что «соответствует любому из: a
, любому символу между c
и e
или g
". Таким образом, ваше совпадение говорит: «соответствовать любому из: 0
, любому символу между 1
и 1
(, т.е. , только 1
) или 2
.
Ваша цель состоит в том, чтобы указать диапазон чисел: любое число между 01
и 12
, написанное двумя цифрами. В этом конкретном случае вы можете сопоставить его с 0[1-9]|1[0-2]
: либо 0
, за которым следует любое между 1
и 9
или 1
, за которой следует любая цифра между 0
и 2
. В общем случае вы можете преобразовать любой диапазон чисел в действительное регулярное выражение аналогичным образом. более эффективный вариант, чем обычные выражения, или существующая функция или модуль, которые могут создавать регулярное выражение для вас. Это зависит от вашего языка.
Это также работает:
^([1-9]|[0-1][0-2])$
[1-9]
соответствует одиночным цифрам от 1 до 9
[0-1][0-2]
соответствует двойной цифре между 10 и 12
[0-1][0-2]
также соответствует 00
. Тем не менее, +1 для ссылки (которую я использовал в своем ответе).
– polygenelubricants
30 June 2010 в 12:05
[0-1][0-2]
должен быть тщательно интерпретирован, так как он допускает такие строки, как 00
, 01
и 02
, но он не допускает 03
до 09
, допуская, наконец, 10
, 11
и 12
. Правильное регулярное выражение для этого - [1-9]|1[0-2]
или даже 0*([1-9]|1[0-2])
(это последнее позволяет любое количество ведущих нулей).
– Luis Colorado
23 September 2015 в 20:50
Используйте это:
0?[1-9]|1[012]
Чтобы проверить шаблон как 07/2018, используйте это:
/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/
(Диапазон дат между 01/2000 по 12/9999)
Как заявляют полигенные смазочные материалы, ваш поиск будет искать 0 | 1-1 | 2, а не то, что вы хотите, из-за того, что классы символов (вещи в []) соответствуют символам, а не строкам.
0|1-1|2
- эта нотация очень вводит в заблуждение. Что-то вроде 0|1|2
было бы более точным.
– polygenelubricants
30 June 2010 в 11:28
Символьный класс в регулярных выражениях, обозначаемый синтаксисом [...]
, определяет правила, соответствующие одному символу на входе. Таким образом, все, что вы пишете между скобками, указывает, как сопоставить один символ .
Таким образом, ваш шаблон [01-12]
разбит следующим образом:
Итак, в основном все, что вам нужно, это 0, 1 или 2.
Чтобы выполнить нужный вам совпадение, сопоставляя две цифры, начиная с 01- 12 как числа, вам нужно подумать о том, как они будут выглядеть как текст.
У вас есть:
Затем вам нужно будет написать регулярное выражение для это может выглядеть так:
+-- a 0 followed by 1-9
|
| +-- a 1 followed by 0-2
| |
<-+--> <-+-->
0[1-9]|1[0-2]
^
|
+-- vertical bar, this roughly means "OR" in this context
Обратите внимание, что попытка комбинировать их для получения более короткого выражения не удастся, предоставив ложные положительные совпадения для недопустимого ввода.
Например, шаблон [0-1][0-9]
будет в основном соответствовать номерам 00-19, что немного больше, чем вы хотите.
Я попытался найти определенный источник для получения дополнительной информации о классах символов, но на данный момент все, что я могу вам дать, - это Google Query for Классы символов регулярных выражений . Надеюсь, вы сможете найти там больше информации, чтобы помочь вам.
Чтобы решить эту проблему, вы можете использовать /^[0-1][0-9]$/;
. Если вы хотите, чтобы 01
был 12
, вам нужно проверить два условия:
Используется ли значение 00
с помощью if
оператор:
if(thevale=="00")
{
// message to user...not allowed
}
и:
if(thevalue >=13)
{
// message to user...not allowed
}
Пример кода в Javascript:
function CheckMonth(txtBox) {
var ex = /^[0-1][0-9]$/;
if (txtBox.value.trim() != "") {
if (txtBox.value.trim() == "00") {
alert('Please enter valid numbers.');
txtBox.value = "";
txtBox.focus();
}
else if (ex.test(txtBox.value.trim()) == false) {
alert('Please enter valid numbers.');
txtBox.value = "";
txtBox.focus();
}
else if (parseInt(txtBox.value.trim()) >= 13) {
alert('Please enter valid numbers.');
txtBox.value = "";
txtBox.focus();
}
}
}
0[1-9]|1[0-2]
не будет работать. Переход к логическому следующему шагу[1-9]|1[0-2]
не работает ни по понятным причинам (он соответствует1
только в10
,11
и12
). Пришлось использовать\b(?:[0-9]|1[0-1])\b
, чтобы предотвратить это.\b
делает, чтобы регулярное выражение соответствовало границам слов (или в этом случае) (^
& amp;$
не было); скобки делают или (|
) рассматривают другую сторону; и, наконец,?:
состоит в том, чтобы не создавать подделки с использованием скобок. – user66001 13 April 2017 в 19:05"1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )
Не могли бы вы рассказать мне, почему это регулярное выражение JS соответствует 17? – edam 24 January 2018 в 14:39