Frage

In Ruby Ich bin Parsen ein Datum in folgendem Format: 24.092.008. Ich mag jeden Abschnitt (Jahr, Monat, Datum) in eine Zahl umgewandelt werden.

Ich habe sie aufgespalten eine Regex, die drei Saiten erzeugt, die ich in den Integer-Konstruktor bin übergeben.

  date =~ /^([\d]{2})([\d]{2})([\d]{4})/
  year = Integer($3)
  month = Integer($2)
  day = Integer($1)

Wenn es den Monat Linie trifft es stürzt ab wie folgt:

`Integer': invalid value for Integer: "09" (ArgumentError)

Es dauerte eine Weile, zu erkennen, dass sie die führenden Null als Octals Interpretieren und 09 ist keine gültige Octal-Nummer (es funktioniert gut mit „07“).

Gibt es eine elegante Lösung für dieses oder sollte ich gerade testen Sie für Zahlen von weniger als 10 und die Null zuerst entfernen?

Danke.

War es hilfreich?

Lösung

Ich bin nicht vertraut mit regulären Ausdrücken, so verzeihen Sie mich, wenn diese off-base Antwort. Ich habe unter der Annahme, dass 3, $ 2 $ und 1 $ sind Strings. Hier ist, was ich in IRB hat, das Problem zu reproduzieren:

irb(main):003:0> Integer("04")
=> 4
irb(main):004:0> Integer("09")
ArgumentError: invalid value for Integer: "09"
    from (irb):4:in `Integer'
    from (irb):4
    from :0

Aber es sieht aus wie .to_i nicht die gleichen Probleme hat:

irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9

Andere Tipps

Geben Basis 10

Tell Rubin ausdrücklich, dass Sie die Zeichenfolge als Basis 10 Nummer interpretieren wollen.

Integer("09", 10) # => 9

Dies ist besser als .to_i, wenn Sie streng sein wollen .

"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError

Wie ich das herausgefunden

In irb, method(:Integer) kehrt #<Method: Object(Kernel)#Integer>. Das sagte mir, dass Kernel diese Methode besitzt, und ich sah die Dokumentation auf Kernel auf. die Methodensignatur zeigt, dass es sich um eine dauert Basis als zweites Argument.

Vielleicht (0([\d])|([1-9][\d])) anstelle von ([\d]{2}) Sie können 3 $ 2, $ 4 und $ 5 anstelle von $ 1, $ 2, $ verwenden.

Oder wenn Ihr regexp unterstützt (?:...) dann verwenden (?:0([\d])|([1-9][\d]))

Da Rubin seine regexp von Perl nimmt, sollte diese letztere Version arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top