如何拆分包含分隔符和转义分隔符的字符串?

时间:2012-06-22 21:15:11

标签: ruby regex

我的字符串分隔符为;。分隔符作为\;在字符串中转义。如,

irb(main):018:0> s = "a;b;;d\\;e"
=> "a;b;;d\\;e"
irb(main):019:0> s.split(';')
=> ["a", "b", "", "d\\", "e"]

有人可以建议我使用正则表达式,所以拆分的输出是["a", "b", "", "d\\;e"]吗?我正在使用Ruby 1.8.7

2 个答案:

答案 0 :(得分:6)

如果没有Oniguruma(可以编译),1.8.7没有负面的背后隐藏。

1.9.3;耶:

> s = "a;b;c\\;d"
=> "a;b;c\\;d"
> s.split /(?<!\\);/
=> ["a", "b", "c\\;d"]

1.8.7 Oniguruma不提供简单的分割,但你可以获得匹配偏移并以此方式拉开子串。我认为有一种更好的方法可以做到这一点我不记得了:

> require 'oniguruma'
> re = Oniguruma::ORegexp.new "(?<!\\\\);"
> s = "hello;there\\;nope;yestho"
> re.match_all s
=> [#<MatchData ";">, #<MatchData ";">]
> mds = re.match_all s
=> [#<MatchData ";">, #<MatchData ";">]
> mds.collect {|md| md.offset}
=> [[5, 6], [17, 18]]

其他选项包括:

  • 分割;并对结果进行后期处理,以查找尾随\\
  • 执行char-by-char循环并保持一些简单状态,然后手动拆分。

答案 1 :(得分:2)

正如@ dave-newton回答的那样,你可以使用负面的lookbehind,但1.8中不支持。在1.8和1.9中都可以使用的替代方法是使用String#scan而不是split,使用不接受(分号或反斜杠)的模式或者以反冲为前缀的anychar:

$ irb
>> RUBY_VERSION
=> "1.8.7"
>> s = "a;b;c\\;d"
=> "a;b;c\\;d"
s.scan /(?:[^;\\]|\\.)+/
=> ["a", "b", "c\\;d"]