Ruby 将regexp作为参数写入gsub!方法——难倒?
在我的Rails 4.2.6/Ruby 2.2.4应用程序中,我有一个生成字符串的db查询方法;例如:Ruby 将regexp作为参数写入gsub!方法——难倒?,ruby,regex,ruby-on-rails-4,gsub,Ruby,Regex,Ruby On Rails 4,Gsub,在我的Rails 4.2.6/Ruby 2.2.4应用程序中,我有一个生成字符串的db查询方法;例如: "Chest - pectoralis, Quads - quadriceps, Hamstrings - biceps femoris" 然而,我想要的结果是: "Chest, Quads, Hamstrings" 该域跟踪21个肌肉组,这意味着生成的字符串可以有许多不同的组合。但是,字符串将始终具有相同的模式,即:“公共肌肉名称-技术肌肉名称” 使用条件逻辑,我可以通过将“字符串”参数
"Chest - pectoralis, Quads - quadriceps, Hamstrings - biceps femoris"
然而,我想要的结果是:
"Chest, Quads, Hamstrings"
该域跟踪21个肌肉组,这意味着生成的字符串可以有许多不同的组合。但是,字符串将始终具有相同的模式,即:“公共肌肉名称-技术肌肉名称”
使用条件逻辑,我可以通过将“字符串”参数传递给gsub方法来获得想要的结果,如下所示:
if @muscle_group_ids == [1, 13, 14]
@muscle_group_names = MuscleGroup.where(id: @muscle_group_ids).map { |n| n[:name]
}.join(', ').gsub!("Chest - pectoralis", "Chest").gsub!("Quads - quadriceps", "Quads").gsub!("Hamstrings - biceps femoris", "Hamstrings")
end
=> "Chest, Quads, Hamstrings"
if @muscle_group_ids == [1, 13, 14]
@muscle_group_names = MuscleGroup.where(id: @muscle_group_ids).map { |n|
n = n[:name].split(" -")[0]
}.join(', ')
end
=> "Chest, Quads, Hamstrings"
这种方法是不可行的;它既乏味又脆弱。必须有更好的方法从生成的字符串中删除破折号和技术名称。我被如何最好地完成这件事难倒了。是否有可能编写一个regexp来实现期望的结果,以及如何编写?有没有更简单、更好、更干净的方法来实现我的目标?谢谢 像这样
irb(main):001:0> s="Chest - pectoralis, Quads - quadriceps, Hamstrings - biceps femoris"
irb(main):002:0> s.gsub(/(\w+)\s+-\s+[^,]*/, '\1')
=> "Chest, Quads, Hamstrings"
它搜索任意数量(+
)的“word”字符(\w)
,它记住这些字符是因为它们在括号中,后跟空格(\s+
)、连字符、更多空格以及任何非逗号的字符([^,]*
)。它仅用它记住的单词字符(\1
)替换所有这些字符
该模式非常具体,例如,如果通用名称可能不止一个单词,则需要对其进行修改
另外,我刚才做了上面的gsub
来返回(并在irb
中显示)结果;要在适当的位置修改字符串,可以使用gsub代码>肌肉群#通用名
最简单的方法是在MuscleGroup
模型中定义一个新方法:
def common_name
name.split(' - ').first
end
您的代码变成:
@muscle_group_names = MuscleGroup.where(id: @muscle_group_ids).map { |muscle_group|
muscle_group.common_name }.join(', ')
双重分裂
如果出于某种原因,您已经有了一个完整的字符串,那么双拆分可能比大型regexp更健壮、更易于阅读
您可以围绕,“
进行拆分,以获得“普通肌肉名称-技术肌肉名称”
的数组。然后,您可以将这些字符串中的每一个拆分为“-”
,并保留第一部分:
"Chest - pectoralis, Quads - quadriceps, Hamstrings - biceps femoris".
split(', ').map{|s| s.split(' - ').first}
# ["Chest", "Quads", "Hamstrings"]
获得数组后,可以重新连接到字符串:
"Chest - pectoralis, Quads - quadriceps, Hamstrings - biceps femoris".
split(', ').map{|s| s.split(' - ').first}.join(', ')
# "Chest, Quads, Hamstrings"
您可以在map函数中拆分“-”
上的名称,并只返回第一部分,如下所示:
if @muscle_group_ids == [1, 13, 14]
@muscle_group_names = MuscleGroup.where(id: @muscle_group_ids).map { |n| n[:name]
}.join(', ').gsub!("Chest - pectoralis", "Chest").gsub!("Quads - quadriceps", "Quads").gsub!("Hamstrings - biceps femoris", "Hamstrings")
end
=> "Chest, Quads, Hamstrings"
if @muscle_group_ids == [1, 13, 14]
@muscle_group_names = MuscleGroup.where(id: @muscle_group_ids).map { |n|
n = n[:name].split(" -")[0]
}.join(', ')
end
=> "Chest, Quads, Hamstrings"
如果共同的名字有两个词呢?谢谢。这些都是很好的答案。我给其他答案加了分。@codeinspired:如果有什么问题,lassvi应该得到被接受的答案。他是第一个注意到您正在逆向处理问题的人,并提出了一个更干净的解决方案。作为旁白,不要在Rails中使用MuscleGroup.where(…).map{n | n[:name]}
,如果您可以这样做:MuscleGroup.where(…).pull(:name)