Почему диапазон [01-12] работает не так, как ожидалось?


Я пытаюсь использовать шаблон диапазоне [01-12] в регулярном выражении, чтобы соответствовать двухзначный мм, но это не работает, как ожидалось.

7 63

7 ответов:

вы, кажется, неправильно поняли, как определение классов символов работает в регулярном выражении.

чтобы соответствовать любой из строк 01,02,03,04,05,06,07,08,09,10,11 или 12, что-то вроде это работает:

0[1-9]|1[0-2]

ссылки


объяснение

класс символов, сам по себе, пытается соответствовать один и ровно один символ из входной строки. [01-12] на самом деле определяет [012], класс символов, который соответствует одному символу из входных данных против любого из 3 символов 0,1 или 2.

The - определение диапазона идет от 1 to 1, которая включает в себя только 1. С другой стороны, что-то вроде [1-9] включает в себя 1,2,3,4,5,6,7,8,9.

Новички часто делают ошибки в определении вещи, как [this|that]. Это не"работает". Это определение символа определяет [this|a], т. е. он соответствует одному символу из входных данных против любого из 6 символов в t,h,i,s,| или a. Больше чем скорее (this|that) это то, что предназначено.

ссылки


как определяются диапазоны

так что теперь очевидно, что шаблон, как between [24-48] hours не "работать". Класс символов в этом случае эквивалентен [248].

то есть - в классе символов определение не определяет числовой диапазон в шаблоне. Механизмы регулярных выражений на самом деле не "понимают" числа в шаблоне, за исключением синтаксиса конечного повторения (например,a{3,5} матчи между 3 и 5 a).

определение диапазона вместо этого использует кодировку ASCII / Unicode символов для определения диапазонов. Характер 0 кодируется в ASCII как decimal 48;9 составляет 57. Таким образом, определение символа [0-9] включает в себя все символы, значения которых находятся между десятичные числа 48 и 57 в кодировке. Довольно разумно, по дизайну это символы 0,1, ...,9.

см. также


другой пример: от A до Z

давайте посмотрим на другое определение общего класса символов [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)

вопросы

класс символов в регулярных выражениях, обозначаемый [...] синтаксис, задает правила для соответствия один символ на входе. Таким образом, все, что вы пишете между скобками, указывает, как соответствовать один символ.

ваш шаблон, [01-12] таким образом, разбивается следующим образом:

  • 0 - соответствует одной цифре 0
  • или, 1-1, соответствует одной цифре в диапазоне от 1 до 1
  • или, 2, соответствует одной цифре 2

так что в основном все, что вы соответствуете 0, 1 или 2.

для того, чтобы сделать соответствие вы хотите, соответствующие две цифры, начиная от 01-12 в виде чисел, вам нужно думать о том, как они будут выглядеть как текст.

у вас есть:

  • 01-09 (т. е. первая цифра 0, вторая цифра 1-9)
  • 10-12 (т. е. первая цифра-1, вторая цифра 0-2)

затем вам придется написать обычный выражение для того, что может выглядеть так:

  +-- 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 для классов символов регулярных выражений. Надеюсь, вы сможете найти там дополнительную информацию, которая поможет вам.

Это также работает:

^([1-9]|[0-1][0-2])$

[1-9] соответствует одной цифры от 1 до 9

[0-1][0-2] соответствует двузначным числам между 10 и 12

есть несколько хороших примеров здесь

поскольку polygenelubricants говорит, что Ваш будет искать 0/1-1/2, а не то, что вы хотите, из-за того, что классы символов (вещи в []) соответствуют символам, а не строкам.

The []s в регулярном выражении обозначают a класс персонажа. Если диапазоны не указаны, это неявно или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. В общем случае вы можете преобразовать любой диапазон чисел в допустимое регулярное выражение аналогичным образом. Однако может быть лучший вариант, чем регулярные выражения, или существующая функция или модуль, которые могут построить регулярное выражение для вас. Это зависит от вашего языка.

используйте этот:

0?[1-9]|1[012]
  • 07: допустимый
  • 7: допустимый
  • 0: Не матч
  • 00 : не соответствует
  • 13 : Не матч
  • 21 : Не матч

чтобы проверить шаблон, как 07/2018 используйте это:

/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/

(диапазон дат от 01/2000 до 12/9999)

чтобы решить эту проблему, вы можете использовать /^[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();
            }
        }
    }