كيف يمكنني تحليل رقم من سلسلة قد يكون لها صفر بادئ؟
سؤال
في روبي أقوم بتحليل التاريخ بالتنسيق التالي:24092008.أريد تحويل كل قسم (السنة والشهر والتاريخ) إلى رقم.
لقد قمت بتقسيمها باستخدام التعبير العادي الذي ينتج ثلاث سلاسل أقوم بتمريرها إلى مُنشئ العدد الصحيح.
date =~ /^([\d]{2})([\d]{2})([\d]{4})/
year = Integer($3)
month = Integer($2)
day = Integer($1)
عندما يصل إلى سطر الشهر فإنه يتعطل على النحو التالي:
`Integer': invalid value for Integer: "09" (ArgumentError)
لقد استغرق الأمر بعض الوقت لأدرك أنه يتم تفسير الصفر البادئ على أنه رقم ثماني وأن 09 ليس رقمًا ثمانيًا صالحًا (يعمل بشكل جيد مع "07").
هل هناك حل أنيق لهذا أم يجب علي فقط اختبار الأرقام الأقل من 10 وإزالة الصفر أولاً؟
شكرًا.
المحلول
لست على دراية بالتعابير العادية، لذا سامحني إذا كانت هذه الإجابة غير صحيحة.لقد كنت أفترض أن $3 و$2 و$1 عبارة عن سلاسل.إليك ما فعلته في IRB لتكرار المشكلة:
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
ولكن يبدو أن .to_i لا يواجه نفس المشكلات:
irb(main):005:0> "04".to_i
=> 4
irb(main):006:0> "09".to_i
=> 9
نصائح أخرى
تحديد القاعدة 10
أخبر روبي بوضوح أنك تريد تفسير السلسلة كرقم أساسي 10.
Integer("09", 10) # => 9
هذا هو افضل من .to_i
إذا كنت تريد أن تكون صارمة.
"123abc".to_i # => 123
Integer("123abc", 10) # => ArgumentError
كيف أحسب هذا
في irb
, method(:Integer)
عائدات #<Method: Object(Kernel)#Integer>
.هذا قال لي ذلك Kernel
يمتلك هذه الطريقة، وقد بحثت في الوثائق الموجودة على Kernel. توقيع الطريقة يوضح أنه يأخذ القاعدة كوسيطة ثانية.
ربما (0([\d])|([1-9][\d]))
بدلا من ([\d]{2})
قد تضطر إلى استخدام 2 دولار، و4 دولارات، و5 دولارات بدلاً من 1 دولار، و2 دولار، و3 دولارات.
أو إذا كان التعبير العادي الخاص بك يدعم (?:...)
ثم استخدام (?:0([\d])|([1-9][\d]))
نظرًا لأن روبي تأخذ التعبير العادي الخاص بها من Perl، فيجب أن يعمل هذا الإصدار الأخير.