走过字符串,根据名字字典从电子邮件中猜出一个名字?

Mor*_*ker 1 ruby loops ruby-on-rails email-validation pattern-matching

假设我有一个名字词典(一个巨大的CSV文件).我想从一个没有明显可解析点(., - ,_)的电子邮件中猜出一个名字.我想做这样的事情:

  dict = ["sam", "joe", "john", "parker", "jane", "smith", "doe"]
  word = "johnsmith"
  x = 0
  y = word.length-1
  name_array = []
  for i in x..y
     match_me = word[x..i]
     dict.each do |name|
       if match_me == name
         name_array << name
       end
     end
  end   

  name_array
  # => ["john"]
Run Code Online (Sandbox Code Playgroud)

不错,但我想要"约翰史密斯"或["约翰","史密斯"]

换句话说,我递归循环遍历单词(即未解析的电子邮件字符串,"johndoe@gmail.com"),直到我在字典中找到匹配项. 我知道:这非常低效. 如果有一个更简单的方法,我会全力以赴!

如果没有更好的方法,那么请告诉我如何解决上面的例子,因为它有两个主要缺陷:(1)如何设置循环的长度(参见下面找到"i"的问题), (2)如何在上面的例子中增加"x",以便我可以在给定任意字符串的情况下循环遍历所有可能的字符组合?

找到循环长度的问题,"i":

  for an arbitrary word, how can we derive "i" given the pattern below?

  for a (i = 1)
  a

  for ab (i = 3)
  a
  ab
  b

  for abc (i = 6)
  a
  ab
  abc
  b
  bc
  c

  for abcd (i = 10)
  a
  ab
  abc
  abcd
  b
  bc
  bcd
  c
  cd
  d

  for abcde (i = 15)
  a
  ab
  abc
  abcd
  abcde
  b
  bc
  bcd
  bcde
  c
  cd
  cde
  d
  de
  e
Run Code Online (Sandbox Code Playgroud)

Rea*_*onk 5

r = /^(#{Regexp.union(dict)})(#{Regexp.union(dict)})$/
word.match(r)
=> #<MatchData "johnsmith" 1:"john" 2:"smith">
Run Code Online (Sandbox Code Playgroud)

正则表达式可能需要一些时间来构建,但它的速度非常快.