CSS numerieke uitdrukking, parser en validator

Ik moet voor mijn huidige project numerieke uitdrukkingen parseren en valideren, vergelijkbaar met de codes die worden gebruikt in CSS3's : nth-child() . Kort gezegd is de uitdrukking an + b , waarbij a en b integerwaarden (zowel positief als negatief) moeten zijn. Ze kunnen ook gelijk zijn aan 0 .

Enkele voorbeelden om alles duidelijker te maken: 2n + 1 , 2n , 4 en n + 2 moeten geldig zijn . Kort gezegd zijn a en b elk soort gehele getallen, ondertekend of niet-ondertekend.

De volgende voorbeelden:

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

zijn allemaal geldig. Dit zou alleen moeten mislukken als a of b geen geheel getal is, of als een ander teken in de uitdrukking voorkomt.

Ik zou graag willen weten hoe ik deze uitdrukkingen kan ontleden en valideren; Ik geloof dat een geschikte oplossing REGEXes zou zijn, maar ik heb geen idee hoe ik hier een voor kan bouwen.

0
Als de ingediende expressie overeenkomt met de REGEX, moet deze true retourneren en daarom validatie doorgeven. Ik ben meer geïnteresseerd in de REGEX zelf. Ik gebruik dit in PHP.
toegevoegd de auteur linkyndy, de bron
@CodeJockey, ik implementeer dit in PHP. Ik heb meer voorbeelden gegeven in een opmerking bij uw antwoord.
toegevoegd de auteur linkyndy, de bron
Geef voorbeelden van iets dat mogelijk in de buurt is, maar mag de validatie niet passeren
toegevoegd de auteur Code Jockey, de bron
In welke taal wordt deze uitdrukking toegepast? Java? PHP? .Netto? JavaScript? Is het ook onwenselijk of acceptabel om een ​​ +1 resultaat voor b te hebben?
toegevoegd de auteur Code Jockey, de bron
@linkyndy, ach, sorry, ik lees "evalueren" waar je zei "valideren". Laat mijn commentaar achterwege.
toegevoegd de auteur Bart Kiers, de bron

2 antwoord

EDIT: revised to allow negative numbers as specified in the question END EDIT

Als dit geldige waarden zijn:

5n+12   3456    -5     2     123n+6  8n    13n-6    n+2

En deze zijn ongeldig:

25n.1   4x+4    2n+    6N-2  8n-+5   n+-3  Rn+T     x+1

dan moet deze uitdrukking valideren:

^(-?\d+(n([+-]\d+)?)?)$

Deze uitdrukking zegt:

^           # 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

De TRY s probeert te valideren, maar het maakt niet uit of het er niet is.

EDIT:

Hoewel de bovenstaande expressie moet worden gevalideerd, moet deze expressie precies de resultaten opleveren die u zoekt, met behulp van benoemde capturinggroepen a en b en een positieve lookahead om alleen de getallen voor < code> a en b en om het + -symbool uit te sluiten, maar alleen het - -symbool voor negatieve getallen vast te leggen:

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

Resultaten moeten als volgt zijn:

 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+)?)$

Hiermee wordt de volledige "n" -uitdrukking of niets vastgelegd als er geen is, voor n + 2 , 2 en 12n + 2 produceert dit :

 source    n        a       b
------     ------  ------  ------
 2                          2
 n+2       n                2
 12n+2     12n      12      2
n + 2 moet geldig zijn. Kort gezegd zijn a en b elk soort gehele getallen, ondertekend of niet-ondertekend. 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) zijn allemaal geldig. Dit zou alleen moeten mislukken als a of b geen geheel getal is of als er andere tekens in de expressie voorkomen.
toegevoegd de auteur linkyndy, de bron
Bedankt voor je zeer gedetailleerde antwoord!
toegevoegd de auteur linkyndy, de bron

U wilt zoiets als ^ (?: (?: (-? \ D *) n)? ([+ -] \ d +)? | (\ D +)) $ .
Hiermee worden de twee getallen in de twee succesvolle vastleggroepen geretourneerd.

1
toegevoegd
Dus dit geeft als resultaat of de codes a en b correct zijn geformatteerd (zijnde gehele getallen)? De tekenreeks mag ook niets anders bevatten dan de expressie an + b . Heeft u dit in aanmerking genomen in uw codefragment? Het spijt me, maar mijn vaardigheden bij REGEX zijn erg laag ... :)
toegevoegd de auteur linkyndy, de bron
Bedankt voor je uitleg. Ik weet het, ik zou ze moeten leren.
toegevoegd de auteur linkyndy, de bron
dit legt het tweede nummer vast in een van de twee capture-groepen (de tweede of de derde) en maakt een + vast - geen manier om te weten of je taal parseerstrings kan afhandelen met leading + 's, maar je zou dat kunnen inkorten. Anders is het geldig! ^ (?: (?: (-? \ d +) n)? ([+ -]? \ d +)?) $ wordt vastgelegd in 2 groepen
toegevoegd de auteur Code Jockey, de bron
Het komt alleen overeen als de reeks correct is. Als het overeenkomt, worden de nummers als vanggroepen geretourneerd. Je zou regexes moeten leren.
toegevoegd de auteur SLaks, de bron
@SLaks, uw voorgestelde oplossing komt ook overeen met een lege reeks: ik denk niet dat dit correct is.
toegevoegd de auteur Bart Kiers, de bron