who1 = "I am %{name}."
who2 = "I am %%{name}"
I18n.interpolate(who1, {name: "Tom"}) #=> "I am Tom"
I18n.interpolate(who1, {name: "Tom"}) #=> "I am %{name}"
who1
和 who2
进行分解,期望得到split_who1 = ["I am ", "%{name}", "."]
split_who2 = ["I am ", "%%{name}", "."]
Tome
替换 %{name}
,%%{name}
保留 %{name}
translate_who1 = "I am Tom."
translate_who2 = "I am %{name}."
源代码
module Compiler
TOKENIZER = /(%%\{[^\}]+\}|%\{[^\}]+\})/
protected
# tokenize("foo %{bar} baz %%{buz}") # => ["foo ", "%{bar}", " baz ", "%%{buz}"]
def tokenize(str)
str.split(TOKENIZER)
end
end
正则表达式TOKENIZER
分解:
(%%\{[^\}]+\})
和 (%\{[^\}]+\})
[^\}]+
表示 非 }
一个或一个以上的字符\{[^\{]+\}
表示匹配 {}
内 非 }
一个或一个以上的字符split
方法,参数为Regexp
,()
的字符会被保留eg
a = "test & est"
a.split(/\&/) #=> ["test ", " test"]
a.split(/(\&)/) #=> ["test ", "&", " test"]
split_who1 = who1.split(/(%\{[^\}]+\})/) #=> ["I am ", "%{name}", "."]
split_who2 = who2.split(/(%%\{[^\}]+\})/) #=> ["I am ", "%%{name}", "."]
添加单例方法
who1.i18n_interpolate({name: "Tom"})
who2.i18n_interpolate({})
其中
who1
的 i18n_interpolate
代码段为 "I am #{v{:name}}."
,其中 v = {name: "Tom"}
who2
的 i18n_interpolate
代码段为 "I am %{name}"
主要的代码为:
INTERPOLATION_SYNTAX_PATTERN = /(%)?(%\{([^\}]+)\})/
def compile_if_an_interpolation(string)
if interpolated_str?(string)
string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__
def i18n_interpolate(v = {})
"#{compiled_interpolation_body(string)}"
end
RUBY_EVAL
end
string
end
其中
who1
等价于
def i18n_interpolate(v = {})
str = (t = v[:name] && t.respond_to?(:call) ? t.call : t)
||
(v.has_key?(:name) && '')
||
Raise(MissingInterpolationArgument.new(:name, self))
"I am #{str}"
end
who2
等价于
def i18n_interpolate(v = {})
"I am %{name}"
end
不善于言语~只能贴代码!