2

Chronic 0.9.1 では、解析Febr 2013時に結果が得られJune 2013ます。Feb 2013うまく解析されますが、Febr 2013そうではありません。

問題は、月の省略形が 4 文字の場合だと思います。

する必要がある:

  • 、またはFebr 2013_February 2013
  • 無効にしFebr 2013ます。

私が使用する日付を検証するには:

Chronic.parse(params[:date]).blank?

これはバグですか?回避策を実行できますか? または、これを検証する正しい方法はありますか?

4

1 に答える 1

2

技術的にはバグですが、私はそれを彼らのロジックの穴と呼ぶ傾向があります. Chronic::Repeater.scan_for_month_namesが月を決定する方法は次のとおりです。

# File 'lib/chronic/repeater.rb', line 38

def self.scan_for_month_names(token)
  scan_for token, RepeaterMonthName,
  {
    /^jan[:\.]?(uary)?$/ => :january,
    /^feb[:\.]?(ruary)?$/ => :february,
    /^mar[:\.]?(ch)?$/ => :march,
    /^apr[:\.]?(il)?$/ => :april,
    /^may$/ => :may,
    /^jun[:\.]?e?$/ => :june,
    /^jul[:\.]?y?$/ => :july,
    /^aug[:\.]?(ust)?$/ => :august,
    /^sep[:\.]?(t[:\.]?|tember)?$/ => :september,
    /^oct[:\.]?(ober)?$/ => :october,
    /^nov[:\.]?(ember)?$/ => :november,
    /^dec[:\.]?(ember)?$/ => :december
  }
end

月の名前は、3 文字または完全な名前です。

ソースからそのメソッドを抽出し、ニーズに合わせてパターンを変更してから、そのメソッドを上書きし、パッチとして送信して、微調整が gem の将来のリビジョンに追加されるようにすることができます。または、単語の先頭にある 3 文字の略語を検索し、不要な文字を削除することで、着信文字列を変更できます。


OK、ここで噛むものがあります:

require 'abbrev'

MONTHS = %w[
  january
  february
  march
  april
  may
  june
  july
  august
  september
  october
  november
  december
]

MONTHS_ABBREV = Abbrev.abbrev(MONTHS)
MONTHS_REGEX = /\b(?:j(?:a(?:n(?:u(?:a(?:ry?)?)?)?)?|u(?:ly?|ne?))|s(?:e(?:p(?:t(?:e(?:m(?:b(?:er?)?)?)?)?)?)?)?|a(?:u(?:g(?:u(?:st?)?)?)?|p(?:r(?:il?)?)?)|d(?:e(?:c(?:e(?:m(?:b(?:er?)?)?)?)?)?)?|f(?:e(?:b(?:r(?:u(?:a(?:ry?)?)?)?)?)?)?|n(?:o(?:v(?:e(?:m(?:b(?:er?)?)?)?)?)?)?|o(?:c(?:t(?:o(?:b(?:er?)?)?)?)?)?|ma(?:r(?:ch?)?|y))\b/i

%w[j ja jan janu january f fe feb febr february].each do |m|
  puts "#{ m } => #{ MONTHS_ABBREV[m[MONTHS_REGEX]] }" 
end

どの出力:

j =>
ja => january
jan => january
janu => january
january => january
f => february
fe => february
feb => february
febr => february
february => february

つまり、j一意ではないため、ヒットしません。jaは一意でありjanuary、残りのja...テストと同様に に関連付けられています。fは一意であるため、残りのすべてのf...テストと同様にヒットします。

何をしAbbrev.abbrevますか?渡された単語を、単語全体を識別するために使用される最小の一意の文字列に分割します。4 か月しか使用しない場合は、次のようになります。

require 'abbrev'

MONTHS = %w[
  march
  may
  june
  july
]

MONTHS_ABBREV = Abbrev.abbrev(MONTHS)
pp MONTHS_ABBREV

その結果:

{"marc"=>"march",
 "mar"=>"march",
 "jun"=>"june",
 "jul"=>"july",
 "march"=>"march",
 "may"=>"may",
 "june"=>"june",
 "july"=>"july"}

これらは、正規表現の素晴らしいシード値になります。

どこで手に入れましたMONTHS_REGEXか?うーん...これはRegexp::Assembleと呼ばれるあまり知られていないモジュールを使用した魔法のような Perl コードで、Ruby ではとても恋しいものです。それは卑劣だ...いや、それは...悪魔のように良く、Perlのやり方に密接に結びついており、読んでいると頭痛がする.そうでなければ、私はそれを移植しただろう.

于 2013-06-14T18:39:47.650 に答える