Решение
Можно проверить его с помощью regex - но вы должны предпочесть решение в коде, потому что оно будет намного быстрее. Этому регулярному выражению требуется много возврата. Единственное преимущество этого регулярного выражения состоит в том, что он работает для произвольной длины.
(?:^0+-\d+$)
|
(?:^(?>0*)(?\d+)-(?>0*)\k$)
|
(?:
(?:^(?>0*)(?\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+$)
|
(
(?=^(?>0*)(?\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$)
^
(?>0*)
(?\d*)
(?:(?0)|(?1)|(?2)|(?3)|(?4)|(?5)|(?6)|(?7)|(?8)|(?9))
\d*
-
(?>0*)
\k
(?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!))))))))))
\d*
$
)
)
Это соответствует для каждого x-y
, где x <= y
для положительных целых чисел, включая ледящие нули.
Это не работает для символов.
Объяснение
Мне удалось создать регулярное выражение, которое соответствует x-y
для всех x < y
. Вопрос был x <= y
. Поэтому я разделил вопрос на x = y | x < y
.
Нам нужно обработать, что первое или оба числа содержат только нули, но это тривиально:
^0+-\d+$
Теперь случай x = y
^(?>0*)(?\d+)-(?>0*)\k$
Трудная часть - x < y
.
x
меньше y
, если x
короче длины символа, чем y
(фиксирующие нули захватываются атомной группой): ^(?>0*)(?\d)+-(?>0*)(?<-length>\d)*(?(length)(?!))\d+
Эта первая группа захватывает целое число на один захват за цифру. После разделителя определение балансирующей группы очищает стек захвата и заставляет по меньшей мере еще одну цифру. (?=^(?>0*)(?\d)+-(?>0*)(?<-o>\d)*(?(o)(?!))$)
. После этого алгоритм прост. Начните с начала. Если текущая цифра равна, перейдите к следующей цифре. Если текущий x
-digit медленнее текущего y
-digit, мы закончили и найдено совпадение. Если это медленнее, мы не должны совпадать. Это делается по этой схеме: ^
(?>0*) # cut out leeding zeros
(?\d*)
.*
-
(?>0*) # cut out leeding zeros
\k # both numbers start with the same part
.*
$
И теперь проверка на одну цифру. Есть только 10 возможностей [0-9]. Каждый из них захватывается одной группой: (?0)|(?1)|(?2)|(?3)|(?4)|(?5)|(?6)|(?7)|(?8)|(?9)
Теперь мы можем использовать условия для проверки того, больше ли текущий y
-digit, чем текущий x
-digit. Отобразится для 0 и 1: (?0)|(?1)
: если для текущего x
-digit соответствует 0, для текущего y
-digit есть только [1-9]
. Если 1 соответствует только [2-9]
, возможно. Это можно использовать в условии: (?(g0)[1-9]|...)
, что означает, что если g0
имеет захват [1-9]
, он должен совпадать, иначе остальное должно совпадать. Это комбинируется с: (?(g0)[1-9]|(?(g1)[2-9]|(?(g2)[3-9]|(?(g3)[4-9]|(?(g4)[5-9]|(?(g5)[6-9]|(?(g6)[7-9]|(?(g7)[89]|(?(g8)9|(?!))))))))))
. Последний трюк заключается в том, что ни одна из групп g[0-8]
не была сопоставлена только g9
, и нет большего количества цифр, и совпадение должно завершиться неудачно (?!)
. Все это было объединено со всем регулярным выражением, которое соответствует x-y
для всех x <= y
.