Project

General

Profile

Feature #12304

String#split with a block

Added by sawa (Tsuyoshi Sawada) about 3 years ago. Updated about 3 years ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:75045]

Description

I would like String#split to take an optional block, similar to String#scan with a block.

Suppose I have a regex pattern with captures, and I want to iterate over matches while having access to the information in last match $~. In such case, I can use scan, and access the last match in the block during iteration:

"abcabd".scan(/(a)|(b)/) do
  |s|
  if    $1 then ... # `s` is `"a"`, `"a"`
  elsif $2 then ... # `s` is `"b"`, `"b"`
  end
end

In my use case, I need to iterate over not only the matching patterns, but also the non-matched substrings in between them. For such cases, I need to use split instead of scan. And I would like to do something like the following:

"abcabd".split(/((a)|(b))/) do
  |s|
  if $2    then ... # `s` is `"a"`, `"a"`
  elsif $3 then ... # `s` is `"b"`, `"b"`
  else ...          # `s` is `"c"`, `"d"`, and `$~` should be `nil`
  end
end

With the current functionalities, I attempted to do this:

"abcabd".split(/((a)|(b))/).each do
  ...
end

but it does not work the way I wanted; within the each block, the last match value $~ is nil, and I cannot access the information.

History

Updated by shyouhei (Shyouhei Urabe) about 3 years ago

  • Status changed from Open to Feedback

There are methods like String.each_char.slice_when (and friends). See http://ruby-doc.org/core-2.3.0/Enumerable.html#method-i-slice_when
Doesn't this solve your problem? Then, can you show us a bit more details about your use case?

Also available in: Atom PDF