W jaki sposób analizowania numer z ciągiem znaków, który może mieć zero?

głosy
7

W Ruby Mam parsowania datę w następującym formacie: 24092008. Chcę przekształcić każdą sekcję (rok, miesiąc, dzień) w szeregu.

Mam podzielić je za pomocą wyrażenia regularnego, który produkuje trzy ciągi której jestem przechodzącej do konstruktora Integer.

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

Kiedy trafi na linię miesiąc ulega awarii, co następuje:

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

Zajęło mi trochę czasu, aby uświadomić sobie, że to interpretowania zero jako ósemkowej i 09 nie jest ważna liczba ósemkowa (współpracuje z „07”).

Czy jest eleganckie rozwiązanie tego czy mam po prostu przetestować liczb mniej niż 10 i usunięcia zera w pierwszej kolejności?

Dzięki.

Utwórz 28/09/2008 o 21:30
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
15

Nie jestem zaznajomiony z regexes, więc wybacz mi, jeśli ta odpowiedź jest off-bazy. Byłem przy założeniu, że $ 3, $ 2 i $ 1 są struny. Oto co zrobiłem w IRB do replikowania problem:

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

Ale wygląda na to .to_i nie mają te same problemy:

irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9
Odpowiedział 28/09/2008 o 21:36
źródło użytkownik

głosy
6

Określić podstawę 10

Ruby wyraźnie powiedzieć, że chcesz interpretować ciąg jako liczby podstawy 10.

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

To jest lepsze niż .to_ijeśli chcesz być surowe .

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

Jak to się zorientowali

W irb, method(:Integer)powraca #<Method: Object(Kernel)#Integer>. Który powiedział mi, że Kerneljest właścicielem tej metody, i spojrzał na dokumentację jądra. Podpis sposób wykazuje, że ma podstawę jako drugi argument.

Odpowiedział 22/07/2015 o 14:40
źródło użytkownik

głosy
1

Może (0([\d])|([1-9][\d]))zamiast ([\d]{2}) mogłeś użyć $ 2, 4 $ i $ 5 w miejscu $ 1, $ 2, $ 3.

Lub jeśli regexp obsługuje (?:...)następnie użyj(?:0([\d])|([1-9][\d]))

Od rubin czerpie z regexp Perl, ta ostatnia wersja powinna działać.

Odpowiedział 28/09/2008 o 21:52
źródło użytkownik

głosy
0

Poza tym, używasz regex do tokenize wejściowych. Parsowanie (przypisywanie semantyka) odbywa się w Ruby.

Odpowiedział 28/09/2008 o 21:44
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more