2009-08-19 12 views
1

Nicht sicher, ob dies mit einem regulären Ausdruck Ersetzungsbefehl möglich ist, aber ich habe eine vorhandene Regex ersetzen, die die letzten zwei Ziffern einer Zahl in die gleichen zwei vorangestellten Ziffern konvertiert mit einem Punkt. Dies dient zur Anbindung an ein System, das Währungswerte als "2500" sendet, wobei dies "25,00" Dollar bedeutet.Bedingte Regex ersetzen, wenn Wert kleiner als "nnnn"

Meine bestehende Regex: (\d+)(\d{2})$
Mit ersetzen Syntax: $1.$2

Jetzt habe ich ein Problem, aber, wenn ein Wert durch als „50“ nur zum Beispiel gesendet wird, diese 0,50 und meine regex darstellen könnte, werden scheitern, weil nach 1+ numerisch auf der linken und zwei numerischen genau am Ende der Zeichenfolge gesucht wird.

Wie kann ich all diese Umstände abdecken und habe meine regex thusly ersetzen ersetzen:

2500 = 25.00 
500 = 5.00 
50 = 0.50 
5 = 0.05 

Thanks again, Graham

Update: Für diejenigen fragen, warum dies nicht eine Kluft und String-Format sein kann Job ist, weil ich benutzerdefinierte Programmierung vermeiden muss, um dies zu erreichen. Es muss im Idealfall eine Regex- "Regel" sein, die zusammen mit anderen Regex-Definitionen in einer Datenbank definiert ist, da sie für ein generisches Übersetzungssystem verwendet wird. Es werden eingehende Daten übersetzt, die in mehreren Formattypen vorkommen können, wobei im Allgemeinen ein Feld von "101" in "101A" umgewandelt wird, aber in diesem besonderen Fall für diesen Datentyp ist das Hinzufügen von Werten erforderlich.

Zweites Update: Ich habe mehr darüber nachgedacht, weil ich an eine Datenbank gebunden bin, würde jemand einen besseren Weg, als mit einem% wackyMoney% oder ein anderer ‚token‘ definierte in dem db Feld sehen und Testen Sie dann, ob wir dieses Token im Code treffen, um die C# -String-Formatierung anzuwenden und zu teilen.

Antwort

2

Warum verwenden Sie eine Regexp dafür ?!Es wird keine einfache Möglichkeit sein, dies mit einem einzigen Regexp zu tun, aber Sie könnten es mit mehreren (eins für den Fall 3+ Ziffern, einen für den Fall mit zwei Ziffern, einen für die 1-stellige Fall). Aber ...

Ich weiß nicht, die genaue C# Syntax, aber etwas entlang der Linien von:

sprintf('%0.2f', «var»/100.0) 

scheint genau das zu tun, was Sie wollen, solange Sie Ihre Zahlen sind klein genug, dass Ihre Floating-Point-Typ ist präziser als 0,01. Für das Doppelte reicht das bis in die Billiarden.

bearbeiten 1

Da Sie regexps benötigen, können Sie drei (in Perl-Syntax hier, aber ...) verwenden:

s/^(\d+)(\d{2})$/$1.$2/; # you already have this 
s/^(\d{2})$/0.$1/;   # obvious variant 1 
s/^(\d{1}$/0.0$1/;   # obvious variant 2 

Nur einer von denen wird übereinstimmen (Variante 1 erfordert 3+ Zeichen, Variante 2 genau 2 Zeichen, Variante 3 genau 1 Zeichen), also können Sie diese verwenden, wenn Sie mehrere Regexps anhängen können. Ich könnte all das in Perl in einen regulären Ausdruck bringen, aber ich habe keine Ahnung, ob Sie volle Regexp-Funktionen von Perl haben (ich bezweifle es). Schließlich könnte Perl tun:

s/^(\d+)$/sprintf('%0.2f', $1/100.0)/e 

aber das ist eher Betrug. Hat Ihre Regexp-Engine etwas Ähnliches? Oder du hast gesagt, das ist eine Datenbanksache; können Sie SQL CASE bedingt verwenden?

+0

Eine Regex wird verwendet, weil dies für ein generisches Übersetzungssystem ist und die Übersetzungsregel in der Datenbank für eine Menge eingehender Daten definiert wird, wie ich weiß, in einer normalen Umgebung. Aber das ist nicht normal :) – GONeale

+0

Wow, tolle Antwort. Ich benutze die .NET-Regex-Engine, und ich glaube nicht, dass wir Befehle in Regex so nennen könnten! Wäre nett. Ich denke jedoch, dass Sie definitiv auf etwas mit dem Semikolon abgegrenzten Regex gesetzt sein könnten, ich habe definitiv die Macht, den Regex-Parser ändern zu können, um mehrere Regex-Sätze nach Semikolon zu analysieren, wenn ich nicht mehrzeilig bin out of the box, schauen Sie mal vorbei - vielen Dank. – GONeale

+0

Ich bin froh zu hören, dass ich geholfen habe. – derobert

2

Reguläre Ausdrücke können keinen Inhalt erstellen, der nicht vorhanden ist. Daher können Sie keine Null hinzufügen, die nicht vorhanden ist. Die Antwort lautet also, dass Sie dafür keine regulären Ausdrücke verwenden sollten.

Ihre beste Wette wäre, (Double.Parse(value)/100).ToString("0.00") oder etwas ähnliches zu verwenden.


Da Sie eine generische ruleset in der Datenbank definiert wollen, glaube ich, der Fehler ist, dass Sie numerische Regeln mit String-Regeln sind zu mischen. Sie sollten wahrscheinlich Ihre Datenbank verschiedene Arten von Regeln unterstützen.

Ich denke, Sie sollten eine zusätzliche Spalte haben, die angibt, ob der Wert numerisch oder als Zeichenfolge geändert werden soll. Wenn es numerisch geändert werden soll, könnte die Spalte, die momentan für die Ersetzung verwendet wird, einen Multiplikator oder Ähnliches angeben.

Wenn Sie es noch weiter bringen möchten, könnten Sie einen einfachen Formel-Evaluator haben, der etwas wie: x/100 + " USD". Es gibt viele davon, die bereits für .NET verfügbar sind, und es ist auch nicht schwierig, selbst einen einfachen zu erstellen.

+0

Ich dachte, dies der Fall genau war, muss der Inhalt existieren zuerst. Ich werde nachdenken, aber da ich auf die Nachricht von Derobert geantwortet habe, muss es idealerweise ein generischer, nicht programmierter db-definierter Handler sein. – GONeale

+0

Ich verstehe. Ich habe meine Antwort mit einigen meiner Gedanken aktualisiert. – Blixt

0

Haben Sie einen Grund dafür, die Zeichenfolge nicht in eine Zahl zu konvertieren, durch 100 zu dividieren und mit einer geeigneten Formel in eine Zeichenfolge umzuwandeln?

2

Net reguläre Ausdrücke können ein Spiel Auswerter verwenden, das Spiel zu verwandeln, was auch immer gewünscht wird:

String result = Regex.Replace(
    "test 1 test 20 test 300 test 4000 test 50000", 
    @"\d+", 
    (match => (Double.Parse(match.Value)/100).ToString("0.00"))); 

Das Ergebnis ist:

test 0.01 test 0.20 test 3.00 test 40.00 test 500.00