如何使用正则表达式实现以下结果?
"(apple, banana, _orange)" # => ['apple', 'banana', '_orange']
"apple, banana, _orange" # => []
"(apple)" # => ['apple']
"()" # => []
"(apple,sauce)" # => ['apple', 'sauce']
这是我到目前为止所得到的,但我只能捕获最后一个令牌:
\|(?:(?:,\s)?(\w+))*\|
答案 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 :(得分: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个步骤,但它应该比单个正则表达式更具弹性。