在 Chronic 0.9.1 中,解析时Febr 2013
我得到一个 result June 2013
。Feb 2013
解析得很好,但Febr 2013
不是。
我认为问题在于月份缩写有四个字母。
我需要:
- 解析
Febr 2013
为February 2013
, 或 - 无效
Febr 2013
。
要验证我使用的日期:
Chronic.parse(params[:date]).blank?
这是一个错误吗?我可以做周围的工作吗?或者,有正确的方法来验证这一点?
在 Chronic 0.9.1 中,解析时Febr 2013
我得到一个 result June 2013
。Feb 2013
解析得很好,但Febr 2013
不是。
我认为问题在于月份缩写有四个字母。
我需要:
Febr 2013
为February 2013
, 或Febr 2013
。要验证我使用的日期:
Chronic.parse(params[:date]).blank?
这是一个错误吗?我可以做周围的工作吗?或者,有正确的方法来验证这一点?
从技术上讲,这是一个错误,但我更倾向于称其为他们逻辑中的一个漏洞。以下是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
月份名称可以是三个字母,也可以是整个名称。
您可以从源中提取该方法,修改模式以满足您的需求,然后覆盖该方法,并将其作为补丁提交,以便将调整添加到 gem 的未来修订版中。或者,您可以通过在单词开头搜索三个字母的缩写并修剪无关字符来修改传入的字符串。
好的,这里有一些值得咀嚼的东西:
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
?它将传入的单词分解为用于标识整个单词的最小唯一字符串。如果我只使用四个月,情况如下:
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
?嘿......这是一些神奇的 Perl 代码,它使用了一个鲜为人知的模块Regexp::Assemble,我在 Ruby 中非常想念它。它很恶心......不,它......非常好并且与 Perl 的工作方式密切相关,当我阅读它时让我头疼,否则我会移植它。