如何在括号内获取每个逗号分隔的标记

时间:2017-01-22 02:45:03

标签: ruby regex

如何使用正则表达式实现以下结果?

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

这是我到目前为止所得到的,但我只能捕获最后一个令牌:

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

2 个答案:

答案 0 :(得分: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)

示例输出:

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

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

  1. 首先需要检查字符串的开头和结尾 partenthesis
  2. 然后你需要用第二个正则表达式\ b \ w + \ b
  3. 扫描字符串

答案 1 :(得分:1)

您可以使用此正则表达式:

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

在parens之间扫描文本,然后将其拆分为','

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个步骤,但它应该比单个正则表达式更具弹性。