默认情况下,#split
方法的工作方式如下:
"id,name,title(first_name,last_name)".split(",")
将为您提供以下输出:
["id", "name", "title(first_name", "last_name)"]
但我想要如下内容:
["id", "name", "title(first_name,last_name)"]
因此,我使用以下正则表达式(来自 this answer )使用 split 获得所需的输出:
"id,name,title(first_name,last_name)".split(/,(?![^(]*\))/)
但是,当我再次使用另一个字符串时,这是我上面的实际输入,逻辑失败了。我的实际字符串是:
"id,name,title(first_name,last_name,address(street,pincode(id,code)))"
它给出了以下输出:
["id", "name", "title(first_name", "last_name", "address(street", "pincode(id,code)))"]
而不是
["id", "name", "title(first_name,last_name,address(street,pincode(id,code)))"]
最佳答案
更新的答案
由于之前的答案没有处理评论中正确指出的所有情况,我正在用另一个解决方案更新答案。
此方法使用分隔符 |
分隔有效逗号,然后使用它通过 String#split
拆分字符串。
class TokenArrayParser
SPLIT_CHAR = '|'.freeze
def initialize(str)
@str = str
end
def parse
separate_on_valid_comma.split(SPLIT_CHAR)
end
private
def separate_on_valid_comma
dup = @str.dup
paren_count = 0
dup.length.times do |idx|
case dup[idx]
when '(' then paren_count += 1
when ')' then paren_count -= 1
when ',' then dup[idx] = SPLIT_CHAR if paren_count.zero?
end
end
dup
end
end
%w(
id,name,title(first_name,last_name)
id,name,title(first_name,last_name,address(street,pincode(id,code)))
first_name,last_name,address(street,pincode(id,code)),city(name)
a,b(c(d),e,f)
id,name,title(first_name,last_name),pub(name,address)
).each {|str| puts TokenArrayParser.new(str).parse.inspect }
# =>
# ["id", "name", "title(first_name,last_name)"]
# ["id", "name", "title(first_name,last_name,address(street,pincode(id,code)))"]
# ["first_name", "last_name", "address(street,pincode(id,code))", "city(name)"]
# ["a", "b(c(d),e,f)"]
# ["id", "name", "title(first_name,last_name)", "pub(name,address)"]
我相信这可以进一步优化。
关于ruby-on-rails - 使用 String#split 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48049938/