#php #regex
#php #регулярное выражение
Вопрос:
Мне нужно для моего текущего проекта анализировать и проверять числовые выражения, аналогичные тем, которые используются в CSS3 :nth-child()
. По сути, выражение an b
, где a
и b
должно быть целочисленными значениями (как положительными, так и отрицательными). Они также могут быть равны 0
.
Несколько примеров, чтобы сделать все более понятным: 2n 1
, 2n
, 4
и n 2
должны быть действительными. В основном, a
и b
представляют собой любые целые числа, со знаком или без знака.
Следующие примеры:
n (a=1, b=0)
n 1 (a=1, b=1)
1 (a=0, b=1)
2n 1 (a=2, b=1)
23n 45 (a=23, b=45)
2n-2 (a=2, b=-2)
-1 (a=0, b=-1)
-2n (a=-2, b=0)
все они действительны. Это должно завершиться неудачей только тогда, когда a
or b
не является целым числом или если в выражении присутствует какой-либо другой символ.
Я хотел бы знать, как я могу анализировать и проверять эти выражения; Я считаю, что подходящим решением будут регулярные выражения, но я понятия не имею, как я могу создать его для этого.
Комментарии:
1. Если отправленное выражение соответствует РЕГУЛЯРНОМУ выражению, оно должно возвращать true и, следовательно, проходить проверку. Меня больше интересует само РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ. Я использую это в PHP.
2. Пожалуйста, приведите примеры чего-то, что может быть близко, но не должно проходить проверку
3. @linkyndy, ах, извините, я прочитал «оценить», где вы сказали «проверить». Не обращайте внимания на мой комментарий.
4. На каком языке реализуется это выражение? Java? PHP? .Net? JavaScript? Кроме того, нежелательно или приемлемо иметь
1
результат дляb
?5. @CodeJockey, я реализую это на PHP. Я привел больше примеров в комментарии к вашему ответу.
Ответ №1:
РЕДАКТИРОВАТЬ: исправлено, чтобы разрешить отрицательные числа, как указано в КОНЦЕ вопроса РЕДАКТИРОВАТЬ
Если это допустимые значения:
5n 12 3456 -5 2 123n 6 8n 13n-6 n 2
И они недопустимы:
25n.1 4x 4 2n 6N-2 8n- 5 n -3 Rn T x 1
затем это выражение должно проверять:
^(-?d (n([ -]d )?)?)$
Это выражение говорит:
^ # Assert beginning of line
(d # Match one or more digits
(n # TRY to Match a literal n character
( d # TRY to match a literal plus character followed by one or more digits
)? # END TRY
)? # END TRY
) # End Match
$ # Assert at end of string
TRY
s попытается выполнить проверку, но не будет возражать, если его там нет.
Редактировать:
Хотя приведенное выше выражение должно проверяться, это выражение должно давать именно те результаты, которые вы ищете, используя именованные группы захвата a
и b
, и положительный прогноз для захвата только чисел для a
и b
и для исключения
символа, но только для захвата -
символа для отрицательных чисел:
^(?:(?:(?P<a>-?d*)n)?(?=[ -]?d |$) ?(?P<b>-?d )?)$
Результаты должны быть следующими:
source a b
------ ------ ------
5n 12 5 12
3456 3456
2 2
123n 6 123 6
8n 8
-5 -5
13n-6 13 -6
n 2 2
n
Поскольку я не совсем уверен, как <null value or nothing>
,zero length or null string>
работает дихотомия vs в PHP и preg_match_all
, я бы рекомендовал использовать это выражение, если у вас возникнут какие-либо проблемы с различением результатов для n 2
и 2
:
^(?:(?P<n>(?P<a>-?d*)n)?(?=[ -]?d |$) ?(?P<b>-?d )?)$
Это захватывает все выражение «n» или ничего, если его нет, для n 2
, 2
, и 12n 2
, это производит:
source n a b
------ ------ ------ ------
2 2
n 2 n 2
12n 2 12n 12 2
Комментарии:
1.
n 2
должно быть допустимым. В принципе,a
иb
являются любыми целыми числами, подписанными или беззнаковыми.n (a=1, b=0)
,n 1 (a=1, b=1)
,1 (a=0, b=1)
,2n 1 (a=2, b=1)
,23n 45 (a=23, b=45)
,2n-2 (a=2, b=-2)
,-1 (a=0, b=-1)
,-2n (a=-2, b=0)
все допустимы. Это должно завершиться неудачей только тогда, когдаa
orb
не является целым числом, или если в выражении присутствуют некоторые другие символы.
Ответ №2:
Вы хотите что-то вроде ^(?:(?:(-?d*)n)?([ -]d )?|(d ))$
.
Это вернет два числа в двух успешных группах захвата.
Комментарии:
1. Итак, это возвращает
a
b
, правильно ли отформатированы числа и (будучи целыми числами)? Кроме того, строка не должна содержать ничего, кромеan b
выражения. Вы учли это в своем фрагменте кода? Прошу прощения, но мои навыки в регулярных выражениях очень низки … 🙂2. Он будет соответствовать, только если строка правильная. Если он соответствует, он вернет числа в виде групп захвата. Вы должны изучить регулярные выражения.
3. Спасибо за ваши объяснения. Я знаю, я должен их изучить.
4. это захватывает второе число в одну из двух групп захвата (либо вторую, либо третью) и захватывает
— нет способа узнать, может ли ваш язык обрабатывать строки синтаксического анализа с ведущими
, но вы могли бы это обрезать. В противном случае он действителен!
^(?:(?:(-?d )n)?([ -]?d )?)$
захватывает в 2 группы5. @SLaks, предлагаемое вами решение также соответствует пустой строке: я не думаю, что это правильно.