Given the string "a += 10", separate the string into the left term, right term and operator. Your first instinct might be to split on whitespace, and it would work in this case. But what about "a = b + 10" or "a=10"? Ruby provides a method similar to split called partition.
The partition method will search for a substring to split on and then return all the characters to the left of the substring, the substring itself and all the charaters to the right of the substring. The partition method will only split the string once, and will return these three strings in an array. This can provide a bit more flexibility than split since split will remove the substring it splits on.
In this example, the string will be split on the . character, and the three substrings returned as an array.
1.9.3p0 :001 > "alice.bob".partition('.') => ["alice", ".", "bob"]
The partition method can take a single argument. This argument can either be a string to match a substring exactly, or a regular expression to match a substring more flexibly. We can use a regular expression to solve our original problem. All we need to do is partition on a string of operator characters.
1.9.3p0 :001 > "a = b + 10".partition(/[-=*\/]+/) => ["a ", "=", " b + 10"] 1.9.3p0 :002 >
Should the partition not find the substring, an array of three strings will still be returned. The entire string will be in the first string of the array, and the other two strings will be empty.
1.9.3p0 :001 > "alice.bob".partition('z') => ["alice.bob", "", ""]
Something Similar Using Split
Normally, the split method will remove any match is finds. However, you can use positive lookahead regular expressions to do something similar to the partition method. Positive lookahead regular expressions will match part of a string, but not consume that part of the string.
The syntax for using positive lookahead regular expressions is (?=...) inside a regular expression. So, back to our expression parser. We can use positive lookahead regular expressions to split a string like "a = b + 10" into ["a ", "= b + 10"].
1.9.3p0 :001 > "a = b + 10".split(/(?==)/) => ["a ", "= b + 10"]