CSS лікавае выраз парсер і валідатар

Мне трэба для майго бягучага праекта сінтаксічнага аналізу і пацверджанняў лікавых выразаў, аналагічнага тым, якія выкарыстоўваюцца ў CSS3 ў : п-га дзіцяці() . У асноўным, гэта выраз ап + б , дзе а і б павінен быць цэлыя значэння (як станоўчыя, так і адмоўныя). Яны таксама могуць быць роўныя 0 .

Некаторыя прыклады, каб зрабіць усё больш ясна: 2n + 1 , 2n , 4 і п + 2 павінен быць сапраўдным , У асноўным, а і б з'яўляюцца любыя цэлыя лікі, знакам або без знака.

Наступныя прыклады:

  • 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)

усе сапраўдныя. Гэта павінна трываць няўдачу толькі тады, калі а або б не з'яўляецца цэлым лікам, або калі які-небудзь іншы сімвал прысутнічае ў выразе.

Я хацеў бы ведаць, як я магу разабраць і праверыць гэтыя выразы; Я лічу прыдатным рашэннем было б рэгулярных выразаў, але я паняцця не маю, як я магу стварыць для гэтага.

0
Калі пададзеная выраз адпавядае Regex, яна павінна вяртаць дакладна, і таму праходзіць праверку. Я больш зацікаўлены ў самым Regex. Я выкарыстоўваю гэта ў PHP.
дададзена аўтар linkyndy, крыніца
@CodeJockey, я рэалізую гэта ў PHP. Я прадставіў некалькі прыкладаў у каментары да вашага адказу.
дададзена аўтар linkyndy, крыніца
Просьба прывесці прыклады тое, што можа быць блізка, але не павінны прайсці праверку
дададзена аўтар Code Jockey, крыніца
Якая мова рэалізуе гэты выраз? Java? PHP? .Net? JavaScript? Акрамя таго, гэта непажадана або прымальна мець + 1 вынік для B ?
дададзена аўтар Code Jockey, крыніца
@linkyndy, ах, прабачце, я прачытаў «ацэньваць", дзе вы сказалі, «пацвердзіць». Нічога мой каментар.
дададзена аўтар Bart Kiers, крыніца

2 адказы

<Моцны> EDIT: revised to allow negative numbers as specified in the question END EDIT

Калі гэтыя дапушчальныя значэння:

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 паспрабуе праверыць, але не будзе пярэчыць, калі яна не існуе.

<Моцны> EDIT:

Хоць прыведзенае вышэй выраз павінна пацвердзіць, гэта выраз павінна вырабляць менавіта тыя вынікі, якія вы шукаеце, з дапамогай найменнага захопу групы а і б , і станоўчага прадпрагляд, каб захапіць толькі нумары для < код> а і б і выключыць + сімвал, але толькі захапіць - сімвал для адмоўных лікаў:

^(?:(?:(?P-?\d*)n)?(?=[+-]?\d+|$)\+?(?P-?\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

Because I am not completely sure how the vs ,zero length or null string> dichotomy works in PHP and preg_match_all, I would recommend using this expression if you encounter any problems differentiating between the results for n+2 and 2:

^(?:(?P(?P-?\d*)n)?(?=[+-]?\d+|$)\+?(?P-?\d+)?)$

Гэта захоплівае ўсю "N" выраз або нічога, калі не існуе ні для п + 2 , 2 і 12n + 2 , гэта дае :

 source    n        a       b
------     ------  ------  ------
 2                          2
 n+2       n                2
 12n+2     12n      12      2
<Код> п + 2 павінен быць сапраўдным. У асноўным, а і б з'яўляюцца любыя цэлыя лікі, знакам або без знака. <Код> п (а = 1, B = 0) , п + 1 (а = 1, B = 1) , 1 (а = 0, Ь = 1 ) , 2n + 1 (а = 2, Ь = 1) , 23n + 45 (а = 23, B = 45) , 2n -2 (а = 2, Ь = -2) , -1 (а = 0, Ь = -1) , -2n (а = -2, Ь = 0) усе сапраўдныя. Гэта павінна трываць няўдачу толькі тады, калі а або б не з'яўляецца цэлым лікам, або калі некаторыя іншыя сімвалы прысутнічаюць у выразе.
дададзена аўтар linkyndy, крыніца
Дзякуй за вельмі падрабязны адказ!
дададзена аўтар linkyndy, крыніца

Вы хочаце нешта накшталт ^ ((: ??? (- \ d *) п) ([+ -] \ d +) | (\ d +)). $
Гэта верне два ліку ў двух паспяховых груп захопу.

1
дададзена
Такім чынам, гэта вяртае Ці а і б Нумар правільна адфарматаваны (цэлыя лікі)? Акрамя таго, радок не павінна ўтрымліваць нічога іншага, акрамя ап + б выраз. Ці прымалі вы гэта пад увагу ў фрагменце кода? Я прашу прабачэння, але мае навыкі ў Regex вельмі нізка ... :)
дададзена аўтар linkyndy, крыніца
Дзякуй за вашыя тлумачэнні. Я ведаю, я павінен вывучыць іх.
дададзена аўтар linkyndy, крыніца
гэта захоплівае другое лік у адну з дзвюх груп захопу (альбо другога ці трэцяга) і робіць захоп + - няма спосабу даведацца, калі ваш мова можа апрацоўваць разбору радкоў з вядучым + 's, але вы можаце абрэзаць гэта. У адваротным выпадку, гэта дзейнічае! <Код> ^ ((: ????? (- \ d +) п) ([+ -] \ d +)) $ захоплівае на 2 групы
дададзена аўтар Code Jockey, крыніца
Гэта будзе адпавядаць толькі калі радок з'яўляецца правільнай. Калі гэта не адпавядае, ён вяртае лік, як групы захопу. Вы павінны навучыцца рэгулярнымі выразамі.
дададзена аўтар SLaks, крыніца
@SLaks прапанаваў ваша рашэнне таксама адпавядае пусты радку: Я не думаю, што гэта правільна.
дададзена аўтар Bart Kiers, крыніца