我很难理解ActiveSupport::Inflector::camelize
方法中两个相当复杂的正则表达式。
这是camelize
方法的定义:
def camelize(term, uppercase_first_letter = true)
string = term.to_s
if uppercase_first_letter
string = string.sub(/^[a-z\d]*/) { inflections.acronyms[$&] || $&.capitalize }
else
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
end
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
end
我有点难以理解:
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
和
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
请向我解释他们的意思。谢谢。
这表明我试图理解正则表达式以及我如何解释它们的含义。如果你能够解决这个问题并纠正我的错误,将会非常有帮助。
string = string.sub(/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/) { $&.downcase }
根据我所看到的情况,inflections.acronym_regex
来自Inflections
模块中的ActiveSupport::Inflector
类,以及initialize
类的Inflections
方法,
def initialize
@plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
end
acronym_regex
已分配/(?=a)b/
。据我所知http://www.ruby-doc.org/core-2.0.0/Regexp.html#class-Regexp-label-Anchors,
(?=pat) - Positive lookahead assertion: ensures that the following characters match pat, but doesn't include those characters in the matched text
所以/(?=a)b/
确保字符a
在文本中,但我们在匹配的文本中不包含字符a
,字符a
后面的字符必须是字符b
。换句话说,"abc"
会匹配此正则表达式,但"bbc"
与此正则表达式不匹配,"abc"
的匹配文本将为"b"
(而不是"ab"
})。
因此将inflections.acronym_regex
的值合并到此正则表达式/^(?:#{inflections.acronym_regex}(?=\b|[A-Z_])|\w)/
中,我不知道以下哪两个正则表达式结果:
一个。 /^(?:/(?=a)b/(?=\b|[A-Z_])|\w)/
B中。 /^(?:(?=a)b(?=\b|[A-Z_])|\w)/
虽然我认为它是B.根据我的理解,(?:
提供分组而不捕获,(?=
表示积极的先行断言,\b
匹配字边界时外括号和匹配退格在括号内。所以在英语术语中,正则表达式B,当与文本匹配时,会找到一个以a
字符开头的字符串,后跟一个b
字符,以及(1. backspace中的一个) 2.任何大写字母或下划线3.任何英文字母,数字或下划线。
但是,我觉得奇怪的是,将upper_case_first_letter = false
传递给camelize
函数会导致它匹配以字符ab
开头的字符串,因为这似乎不是如何camelize
函数的行为。
string.gsub(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{inflections.acronyms[$2] || $2.capitalize}" }.gsub('/', '::')
正则表达式是:
/(?:_|(\/))([a-z\d]*)/i
我猜这个正则表达式将匹配以_
或/
开头的子字符串,后跟0或更多(大写或小写的英文字母或数字)。此外,对于第一组(?:_|(\/))
,无论我们是否匹配_
或/
,([a-z\d]*)
捕获组将始终被视为第二组。我确实理解了块试图查找的部分inflections.acronyms[$2]
并且在失败的情况下$2.captitalize
。
由于(?:
表示没有捕获分组,因此$1
匹配时_
的值是多少?它还在_
吗?对于.gsub('/', '::')
部分,我猜测它会应用于初始gsub
中的每个匹配,而不是在外部gsub
调用完成后应用于整个字符串?< / p>
道歉真的很长的帖子。请指出我在理解2个正则表达式时的错误,或者如果你能做到的话,可以更好地解释它们。
谢谢。
答案 0 :(得分:0)
然而,我觉得传递upper_case_first_letter =很奇怪 对camelize函数的false应该使它与字符串匹配 从字符ab开始,假设似乎不是 camelize函数的行为如何。
?:
在这里的作用类似于.
,并且匹配字符串(即单个字符),但没有分组,因此匹配位于$&
。
因为(?:表示没有捕获的分组,$ 1的值是多少 当我们匹配_?还在吗?
它是nil
,因为没有捕获。该值位于$2
对于.gsub('/','::')部分,我猜它得到了 应用于初始gsub中的每个匹配,而不是应用 外部gsub调用完成后,整个字符串是什么?
它应用于整个结果gsub
,块返回一个字符串,gsub('/', '::')
在块之外。