2012-06-22 135 views
4

我的字符串分隔符是;。分隔符在字符串中被轉義爲\;。例如,如何拆分包含分隔符和轉義分隔符的字符串?

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

+0

我想你可以用正則表達式做。看到這個問題http://stackoverflow.com/questions/2164211/ruby-split-with-regex-regex-isnt-doing-what-i-want –

回答

6

1.8.7在沒有Oniguruma(可以編譯)時沒有負向後視。

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循環並保持一些簡單的狀態並手動分割。
+0

戴夫,謝謝你的建議。不幸的是,我們還沒有在Ruby 1.8.7中使用Oniguruma gem。我會嘗試你建議的其他選項,但dbenhur的解決方案現在適用於我。 –

+0

我使用char-by-char循環實現了我自己的分割(第二個建議)。即使有空字段,這也可以工作。 –

+0

@svhyd我不確定'scan'也不能處理這種情況,儘管我不太熟悉它是如何知道的。然而,如果您沒有適當的正則表達式支持,那麼這是其中一種情況,「手動」執行是IMO接受的,因爲您的需求非常狹窄。我不確定哪一個會更快,取決於正則表達式引擎在1.8.7中的實現方式 - 如果是Ruby,那麼手動掃描可能會更快。真高興你做到了! –

2

由於@戴夫牛頓回答,你可以使用負向後視,但在1.8不支持。將在兩個1.8和1.9工作的替代,是使用String#scan而不是分裂,帶有花紋接受不反彈前綴(分號或反斜槓)或anychar:

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

謝謝,這對我有用。 –

+0

實際上,如果一個字段有''''本身就有一個空'scan'不會返回一個空字符串,所以我失去了字段的位置信息。例如,如果原始字符串是'a ;; c \\; d',您的解決方案將返回'[「a」,「c \\; d」]'。有沒有辦法分割/掃描結果是「[」a「,」「,」c \\; d「]'? –

+0

我修改了問題以包含一個空字段(即分號本身)。 –

相關問題