I have a string like:
string1: http://localapp/lkasdjasd/answers/156, Lorem ipsum dolor? is it Lorem, nah? | Here is the answer
Need to split the string on first vertical bar after first comma:
arr = line.split(',')
key = arr[0].split('/')[-1].to_i
title = arr[1]
desc = arr[2]
So far I figured out only how to get the key
You can use
/\A(?:[^,]*[^\d,])?(\d+),([^|]*)\|\s*(.+)/
See the Rubular demo. Details:
\A - start of string(?:[^,]*[^\d,])? - an optional sequence of zero or more non-commas and then a char other than a digit and comma(\d+) - Group 1: one or more digits, - a comma([^|]*) - Group 2: zero or more non-pipe chars\| - a | char\s* - zero or more whitespaces(.+) - Group 3: one or more chars other than line break chars as many as possible.See a Ruby demo:
s = 'http://localapp/lkasdjasd/answers/156, Lorem ipsum dolor? is it Lorem, nah? | Here is the answer'
/\A(?:[^,]*[^\d,])?(?<key>\d+),(?<title>[^|]*)\|\s*(?<desc>.+)/ =~ s
puts "Key: #{key}\nTitle: #{title}\nDescription: #{desc}"
Output:
Key: 156
Title: Lorem ipsum dolor? is it Lorem, nah?
Description: Here is the answer
I vote for the answer: https://stackoverflow.com/a/69299320/13841038
on which you can call .to_i and .strip while printing
key.to_i
title.strip
desc.strip
If you don't prefer regex, then below snippet is a modified version of your solution
str = "http://localapp/lkasdjasd/answers/156, Lorem ipsum dolor? is it Lorem, nah? | Here is the answer"
pipe_arr = str.split('|')
arr = pipe_arr[0].split(',')
key = arr[0].split('/')[-1].to_i
title = (arr[1] + ',' + arr[2]).strip
desc = pipe_arr[1].strip
The following answers what is asked for in the title and in the third line, which are unambiguous. That is not consistent with the desired result, however.
r = /\A([^,]*,[^|]*)\|(.*)/x
"Little Miss Muffett, sat on | a tuffet".scan(r).first
#=> ["Little Miss Muffett, sat on ", " a tuffet"]
"Little | Miss, Muffett, sat on |, a | tuffet".scan(r).first
#=> ["Little | Miss, Muffett, sat on ", ", a | tuffet"]
We can write the regular expression in free-spacing mode to make it self-documenting.
r = /
\A # match beginning of string
( # begin capture group 1
[^,]* # match 0 or more chars other than a comma
, # match a comma
[^|]* # match 0 or more chars other than a pipe
) # end capture group 1
\| # match a pipe
(.*) # match 0 or more chars and save to capture group 2
/x # invoke free-spacing regex definition mode
See String#scan for an explanation of how the method treats regular expressions that contain capture groups.1
A second way, that does not use a regular espression, is to use String#index:
def split_it(str)
i = str.index(',')
return nil if i.nil?
j = str.index('|', i+1)
j.nil? ? nil : [str[0,j-1], str[j+1..-1]]
end
split_it("Little Miss Muffett, sat on | a tuffet")
#=> ["Little Miss Muffett, sat on", " a tuffet"]
split_it("Little | Miss, Muffett, sat on |, a | tuffet")
#=> ["Little | Miss, Muffett, sat on", ", a | tuffet"]
1 An alternative, which I will give without explanation, is the following: "Little | Miss, Muffett, sat on |, a | tuffet".match(/\A[^,],[^|]\K|/) && [$`, $'] #=> ["Little | Miss, Muffett, sat on ", ", a | tuffet"].