1

如果在字符串末尾找到来自数组的标记,我想将字符串分成两部分。我试过这个:

x = "Canton Female"
GENDER_TOKENS = ["m", "male", "men", "f", "w", "female", "wom"]

x.partition(/(^|[[:space:]]+)[#{Regexp.union(GENDER_TOKENS)}]$/i)
 #=> ["Canton Female", "", ""]

但是,虽然“女性”这个词是我标记的一部分,但它并没有被分开。如何调整我的正则表达式以使其正确拆分?

4

3 回答 3

3

有点不清楚你在问什么 - 想要的结果是什么?但是,这就是我认为您正在寻找的内容:

GENDER_TOKENS = ["m", "male", "men", "f", "w", "female", "wom"]

"Canton Female".split(/\b(#{Regexp.union(GENDER_TOKENS).source})$/i)
#=> => ["Canton ", "Female"]

"Tom Lord".split(/\b(#{Regexp.union(GENDER_TOKENS).source})$/i)
#=> => ["Tom Lord"]
  • String#split将在每次匹配时拆分字符串;不像String#partition,它返回[head, match, tail]。我这可能就是你想要的?
  • \b是一个词边界锚。这是一个比尝试匹配“行首或空白”更简洁的解决方案。
  • Regexp 联合被包裹在圆括号中以将值组合在一起,而不是方括号。后者使它成为一个字符集,这显然不是你想要的。
  • Regexp#source仅返回正则表达式的内部“文本”;与您使用的(隐式)不同Regexp#to_s,它返回完整的对象,包括选项切换 - 即/(?-mix:m|male|men|f|w|female|wom)/
于 2017-12-21T18:21:15.083 回答
2

为什么不先分开?

parts = x.split
if GENDER_TOKENS.include? parts.last.downcase
  # ...
end

可能不会慢很多,而且更具可读性

于 2017-12-21T18:25:26.240 回答
1
GENDER_TOKENS = %w[m male men f w female wom]
GENDER_REGEX = /\b(?:#{GENDER_TOKENS.join('|')})\z/i
  #=> /\b(?:m|male|men|f|w|female|wom)\z/i

def split_off_token(str)
  idx = str =~ GENDER_REGEX
  case idx
  when nil
    [str]
  when 0
    ['', str]
  else
    [str[0, idx].rstrip, str[idx..-1]]
  end
end

split_off_token("Canton Female")
  #=> ["Canton", "Female"]
split_off_token("Canton M")
  #=> ["Canton", "M"]
split_off_token("wom")
  #=> ["", "wom"]
split_off_token("Canton Fella")
  #=> ["Canton Fella"]
于 2017-12-21T20:09:44.510 回答