найти экземпляры регулярных выражений, преобразовать в целые числа, сделать математику и заменить в одном месте? - PullRequest
0 голосов
/ 14 января 2019

У меня есть длинный строковый ввод, который содержит тайваньские даты. Мне нужно преобразовать их в американские обозначения и оставить их в том же месте ввода. Я создал регулярные выражения, которые сопоставляются с текстом во входных данных, но я не могу найти способ преобразовать эти совпадения в целые числа, выполнить математические операции (чтобы изменить год), а затем заменить новые значения в том же месте, где были старые значения. ,

Тайваньские даты имеют формат гггг / мм / дд.
Например: 107年02月13日, то есть 02/13/2018

До сих пор у меня есть:

input = gets
texto = input.gsub(/\s+/, "")
Date_with_characters = /\d{3}年\d{2}月\d{2}日/
if input.match(Date_with_characters)
  puts "Encuentro fechas con caracteres"
elsif
  puts "NO encuentro un joraca con caracteres"
end

Date_with_slashes = %r{\d{3}/\d{2}/\d{2}}
if input.match(Date_with_slashes)
  puts "Encuentro fechas con barras"
elsif
  puts "NO encuentro un joraca con barras"
end

Приведенный выше код находит все даты (как с символами, так и с косой чертой), но я надеялся, что смогу затем превратить первые 3 индекса в году в целые числа, выполнить математические вычисления, чтобы превратить их в западный календарь, и вернуть их в то же самое место (пропуская движущийся год до конца пока). Мне еще не повезло, и я много чего пробовал.

Большое спасибо!

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Это способ сделать это, который также подтверждает, что даты действительны. Последний по сути является халявой с подходом, который я выбрал.

require 'date'

def convert_date(str)
  str.gsub(/\d{3}年\d{2}月\d{2}日/) do |s|
    dt = DateTime.strptime(s, '%Y年%m月%d日') rescue nil
    (raise ArgumentError, "#{s} is not a valid date") if dt.nil?
    "#{dt.month}/#{dt.day}/#{dt.year.to_i + 1911}"
  end
end

convert_date 'foo 107年02月13日 bar and 106年11月25日 baz'
  #=> "foo 2/13/2018 bar and 11/25/2017 baz" 
convert_date 'foo 107年02月13日 bar and 106年02月29日 baz'
  #=> ArgumentError (106年02月29日 is not a valid date)

См. DateTime :: strptime и Ядро # повышение .

0 голосов
/ 14 января 2019

Вы можете поместить числа в скобках в захватить их значения отдельно и использовать gsub с блоком для выполнения динамической замены:

str = 'foo 107年02月13日 bar'
str.gsub(/(\d{3})年(\d{2})月(\d{2})日/) { "#{$2}/#{$3}/#{$1.to_i + 1911}" }
#=> "foo 02/13/2018 bar"

Внутри блока специальные переменные $1, $2 и $3 относятся к тексту, соответствующему соответствующей группе захвата, то есть "107", "02" и "13" соответственно. Результат блока становится новым значением для сопоставленного текста.

Также существует gsub!!), который выполняет подстановку на месте (то есть изменяет получатель), возвращая nil, если совпадений не найдено. Это может быть полезно, если вы хотите предоставить сообщение в зависимости от того, произошла ли замена:

if input.gsub!(/(\d{3})年(\d{2})月(\d{2})日/) { "#{$2}/#{$3}/#{$1.to_i + 1911}" }
  puts 'dates have been converted'
else
  puts 'no dates could be found'
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...