2016-04-07 3 views
1

Precision (p): Gesamtzahl der Stellen links und rechts vom KommaWie erstelle ich eine Regex, die (p, s) Genauigkeit und Skalierung wie der SQL-Dezimal-Typ entspricht?

Scale (e): Gesamtzahl der Ziffern rechts vom Komma

Erwägen Sie so weit meine folgende regex:

^-?[0-9]+(\.[0-9]{1,3})?$ 
  • -? optional negative Zahl
  • [0-9] Einstimmungen Zahlen 0-9
  • "+" eine beliebige Anzahl von Ziffern
  • "(\. [0-9] {1,3})?" optional dezimal mit 1-3 Ziffern

Beispiel:

100.95 has a precision of 5 and a scale of 2 (5,2) 

Ich weiß, wie auf der rechten Seite nach links, und Gesamtzahl Gesamtzahl zu beschränken, aber nicht sicher, wie die gesamte Wertschöpfungs einzukapseln zu Begrenzen Sie den Teil "p, Präzision", und ignorieren Sie den Zeitraum, wenn es in dieser Anzahl vorhanden ist. Die - muss auch in dieser Gesamtzahl ignoriert werden.

UPDATE:

Dies scheint zu funktionieren ...

^(?=(\D*\d\D*){0,5}$)-?([0-9]+)?(\.?[0-9]{0,2})?$ 

blank line matches 
0 - match 
1 - match 
123 - match 
123.12 - match 
-1 - match 
123.122 - no match 
+0

Ich weiß, Sie fragen Für eine Regex bin ich sicher, dass die Antwort kommt ... sind Sie offen für andere Möglichkeiten, dies zu tun? vielleicht so: https://jsbin.com/moqiru/1/edit?js,console – JordanHendrix

+0

@ user1447679 ich denke mein Code könnte Ihnen helfen. – John

+0

@ JordanHendrix Anerkannt, aber ja, in diesem Fall muss es eine Regex sein. – user1447679

Antwort

1

Sie eine lookahead assertion am Anfang verwenden könnte es genau so viele Ziffern in der Zeichenfolge, um zu überprüfen, wie Sie benötigen .

(?=(\D*\d\D*){5}$) 

, dass Ihren gesamten Ausdruck dies machen würde:

(?=(\D*\d\D*){5}$)^-?[0-9]+(\.[0-9]{1,3})?$ 

(ich bin mit der shorthand character classes\d (Ziffer) und \D (Nicht-Ziffer) der Kürze und, IMO, die Lesbarkeit.)

Es entspricht einer Ziffer \d, möglicherweise umgeben von nicht-stelligen Zeichen \D* ist uns egal, und stellt sicher, dass genau fünf mal {5} vor derentsprichtEnde der Zeichenfolge.

Refiddle demo here


Update:

Hier ist der Ausdruck, den Sie besiedelt, mit ein paar Veränderungen vereinfacht:

^(?=(\D*\d\D*){0,5}$)-?\d*(\.\d{0,2})?$ 

\d ist die gleiche wie [0-9], so Sie haben eine gewisse Redundanz kann entfernt werden.

  • ([\d0-9]+)? könnte wirklich sein, nur \d* (nicht sicher, ob Sie tatsächlich die Capture-Gruppe verwendet wird, in dem Fall, dass Sie die Klammern um es verlassen sollen: (\d*))
  • \.? braucht nicht die ?, da es könnte von 0 Ziffern folgen und die Gruppe es in ist hat ein ? bereits
  • [\d0-9]{0,2} kann nur \d{0,2} sein

Refiddle demo of updated expression here

+0

Das ist super nah und erlaubt mir, auf meine Bedürfnisse abzustimmen. Wenn Sie Ihre Antwort aktualisieren können, um dies aufzunehmen, würde ich es gerne akzeptieren, da ein etwas näheres Lesen der Anforderungen für die p/s funktioniert hätte. Obwohl meine Antwort immer noch Probleme haben kann.^(? = (\ D * \ d \ D *) {0,5} $) -? ([\ D0-9] +)? (\.? [\ D0-9] {0,2})? $ – user1447679

+0

@ user1447679 Ah, ich verstehe was du meinst. Aktualisiert und optimiert. – Wiseguy

+0

Danke. Ja, ich denke ich werde mit 0-9 gehen. \ d erlaubt andere Arten von Werten als 0-9 Ich denke, nicht wahr? – user1447679

0

Als Ergänzung der vorherigen Antwort, Lookahead zu verwenden. Um die Anzahl der Ziffern in der ganzen Zahl zu beschränken, können Sie (?=(?:-?[\.0-9]{3,8}$)|(?:-?[0-9]{1,7}$)) verwenden. 3 bedeutet mindestens 1 Genauigkeit, 1 Maßstab wird benötigt (es ist 3 mit dem Dezimalpunkt); 7 bedeutet eine ganze Zahl mit 7 Genauigkeit.

Es sind wahrscheinlich kleinere Randfälle zu beachten.

Siehe RegEx101.

0

Wenn Sie die „p, Präzision“ Teil beschränken möchten (zB möchten Sie als 5 Präzision begrenzen), könnten Sie tun:

^-?(\d{5}|\d{2}(?=\d*\.\d*)[\d.]{3}\d)$ 

^    # match start of line 
-?    # match - literally; zero or one time 
(    # capturing group starts 
\d{5}|   # match 5 digits (such as, 10095); OR 
\d{2}   # match 2 digits; assert at least 2 digits ahead of dot (.) 
(?=\d*\.\d*) # positive lookahead; assert . (dot) can be matched ahead 
[\d.]{3}  # match a digit or . (dot) three times 
\d    # assert at least one digit at the end 
)    # capturing group ends 
$    # match end of line 

REGEX 101 DEMO

Verwandte Themen