2017-01-22 22 views
0

如何使用正则表达式实现以下结果?如何在括号内获得每个以逗号分隔的标记

"(apple, banana, _orange)" # => ['apple', 'banana', '_orange'] 
"apple, banana, _orange" # => [] 
"(apple)"     # => ['apple'] 
"()"      # => [] 
"(apple,sauce)"   # => ['apple', 'sauce'] 

这是我有这么远,但我只能够捕捉到最后一个记号:

\|(?:(?:,\s)?(\w+))*\| 

回答

1

你可以试试这个:

/\b\w+\b(?=.*\))/m 

it works for all your provided sample

re = /\b\w+\b(?=.*\))/m 
str1 = '(apple, banana, _orange)' 
str2 = 'apple, banana, _orange' 
str3 = '(apple)' 
str4 = '()' 
str5 = '(apple,sauce)' 

p str1.scan(re) 
p str2.scan(re) 
p str3.scan(re) 
p str4.scan(re) 
p str5.scan(re) 

样品输出ut:

["apple", "banana", "_orange"] 
[] 
["apple"] 
[] 
["apple", "sauce"] 

但理想情况下,这不是最好的解决方案,因为它不检查它是否以一个(或不是)开头。 如果你真的要使用正则表达式,那么你不能用一个正则表达式做到完美:

  1. 你首先需要检查字符串开始与 partenthesis结束
  2. ,那么你需要扫描的字符串第二正则表达式\ b \ w + \ b
1

你可以使用这个表达式:

/(?<=\().*?(?=\))/ 

扫描括号之间的文本,然后将它拆分为','

strings = [ 
    '(apple, banana, _orange)', 
    'apple, banana, _orange', 
    '(apple)', 
    '()', 
    '(apple,sauce)', 
    '(apple) orange (sauce)', 
    'not properly closed)' 
] 

strings.each do |string| 
    p string.scan(/(?<=\().*?(?=\))/).flat_map { |s| s.split(',') } 
end 

# => 
# ["apple", " banana", " _orange"] 
# [] 
# ["apple"] 
# [] 
# ["apple", "sauce"] 
# ["apple", "sauce"] 
# [] 

它需要2个步骤,但它应该比只有一个正则表达式更有弹性。