用于命名空间的Ruby类/模块名称的正则表达式

时间:2018-04-21 08:57:51

标签: ruby regex

匹配任何命名空间的Ruby类或模块名称有什么好的正则表达式?
更一般地说,我如何匹配由双冒号分隔的单词序列?

Word1::Word2
Word1::Word2::Word3
Word1::Word2::Word3::Word4

这是我得到的最接近的东西,但它最多只能连续两个单词:

string.scan /[a-zA-Z0-9]+(?:\:\:[a-zA-Z0-9]+)/

2 个答案:

答案 0 :(得分:3)

你的方法很好,你应该只量化捕获组或更短的时间:

\b\w+(?:::\w+)+\b

Live demo

答案 1 :(得分:1)

R = /
    \A         # match beginning of string
    (?:        # begin a non-capture group
      (?:::)?  # optionally match two colons
      \p{Lu}   # match an uppercase letter
      \w*      # match zero or more word characters
    )+         # close non-capture group and execute group one or more times
    \z         # match end of string
    /x         # free-spacing regex definition mode

'AB::CD::EF'.match?(R)           #=> true
'A'.match?(R)                    #=> true
'::A::C_d::E3F_'.match?(R)       #=> true
'AB::cD::EF'.match?(R)           #=> false
'AB:::CD::EF&'.match?(R)         #=> false

或者,我们可以写下以下内容。

def valid_mod_name?(str)
  i = str[0,2]=='::' ? 2 : 0
  str[i..-1].split('::').all? { |s| s.match?(/\A\p{Lu}\w*\z/) }
end

valid_mod_name? 'AB::CD::EF'     #=> true
valid_mod_name? 'A'              #=> true
valid_mod_name? '::A::C_d::E3F_' #=> true
valid_mod_name? 'AB::cD::EF'     #=> false
valid_mod_name? 'AB:::CD::EF&'   #=> false