Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
Here's what I want to happen
> /x(y\d)*/.somefunction('xy1y2y3').each { |x| puts x }
y1
y2
y3
This seems like a pretty natural use of the asterisk in a regexp. I've matched a bunch of tokens and I want them printed out.
The closest I've been able to find is:
/x((y\d)*)/.match('xy1y2y3')[1].scan(/y\d/).each { |x| puts x }
Which is just abysmal.
The issue you are running into has to do with the regex rather than Ruby. You are repeating a capture group rather than capturing a repeated group. You could use
str.scan(/x((?:y\d)*)/)
However, this will capture all of the groups combined as one string. In order to do what you actually want to do (check that the string follows the pattern x followed by these groups) you unfortunately need to do two steps as you are doing in your question. Either that, or you can remove the additional requirement and search only for the pattern as other answers are suggesting.
I assume this is what you want:
'xy1y2y3'.gsub(/y\d/) { |s| puts s }
The gsub method accepts a block.
Based on your input and output, this looks about right:
'xy1y2y3'.scan(/y\d/)
# => ["y1", "y2", "y3"]
Use this if you want to print them:
puts 'xy1y2y3'.scan(/y\d/)
# >> y1
# >> y2
# >> y3
String's scan is your friend if you want to look through a string and capture repeating patterns.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I want to split a query string like:
"(first_name:zach AND last_name:woods) OR (first_name:thomas AND last_name:middleditch) OR (first_name:martin AND last_name:starr) OR "...
into substrings, each not greater than 5000 characters, and I want to split on the pattern " OR ".
Help would be appreciated.
If your query is just like the example, you can just split by OR, then loop through the substrings to join them together until it reaches 5000 characters.
original_query = "(first_name:zach AND last_name:woods) OR ..."
split_arr = original_query.split(/(?<=OR)/) # Split but keeps delimiter OR
result = []
pattern = ""
split_arr.each do |query|
if (pattern.length + query.length) > 5000 # If reached limit
result.push(pattern) # Store the current pattern
pattern = query # Start new substring
else # Else
pattern = pattern + " " + query # Just add more query to current pattern
end
end
result.push(pattern) if pattern.length > 0 # Check for the final case
puts result
Then, you will get the array result with substrings that are less than 5000 characters. However, given your string is an SQL query (maybe), whether the substrings are correct syntactically or not depends on your original query.
It is better to have these query constraints while building the query itself.
If you still want to work with this approach, one way would be to scan the conditions and concatenate them based on the size you preferred.
# Scan all matching conditions
conditions = str.scan(/first_name:[a-z]+ AND last_name:[a-z]+/)
# Final queries array
result = []
# Iterate over the conditions array as batch collection and build query
# Considering average size of each one as 35, batching group of 140 items
conditions.in_groups_of(140) { |group| group.reduce { |x, y| result << (x + (y.nil? ? '' : ' OR '+ y)) } }
The result array would have the queries split by size.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I need to split a string, for food products, such as "Chocolate Biscuits 200g"
I need to extract the "200g" from the String and then split this by number and then by the measurement/weight.
So I need the "200" and "g" separately.
I have written a Ruby regex to find the "200g" in the String (sometimes there may be space between the number and measurement so I have included an optional whitespace between them):
([0-9]*[?:\s ]?[a-zA-Z]+)
And I think it works. But now that I have the result ("200g") that it matched from the entire String, I need to split this by number and measurement.
I wrote two regexes to split these:
([0-9]+)
to split by number and
([a-zA-Z]+)
to split by letters.
But the .split method is not working with these.
I get the following error:
undefined method 'split' for #MatchData "200"
Of course I will need to convert the 200 to a number instead of a String.
Any help is greatly appreciated,
Thank you!
UPDATE:
I have tested the 3 regexes on http://www.rubular.com/.
My issue seems to be around splitting up the result from the first regex into number and measurement.
One way among many is to use String#scan with a regex. See the last sentence of the doc concerning the treatment of capture groups.
str = "Chocolate Biscuits 200g"
r = /
(\d+) # match one or more digits in capture group 1
([[:alpha:]]+) # match one or more alphabetic characters in capture group 2
/x # free-spacing regex definition mode
number, weight = str.scan(r).flatten
#=> ["200", "g"]
number = number.to_i
#=> 200
I'm not an expert in ruby, but I guess that the following code does the deal
myString = String("Chocolate Biscuits 200g");
weight = 0;
unit = String('');
stringArray = myString.split(/(?:([a-zA-Z]+)|([0-9]+))/);
stringArray.each{
|val|
if val =~ /\A[0-9]+\Z/
weight = val.to_i;
elsif weight > 0 and val.length > 0
unit = val;
end
}
p weight;
p unit;
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I have an array with string values:
a = ["Customer name", "Address", "Qualification"]
Requirement is to make these string values enclosed in both single and double quotes like this:
a = ["'Customer name'", "'Address'", "'Qualification'"]
How can I achieve this?
a = ["Customer name", "Address", "Qualification"]
a.map { |i| "'#{i}'" } # => ["'Customer name'", "'Address'", "'Qualification'"]
It makes sense to say that you want to enclose the content of each string with single quotes, but it does not make sense to say that you want to have double quotes around it, that is part of the literal. But anyway,
a.map{|s| "'#{s}'"}
# => ["'Customer name'", "'Address'", "'Qualification'"]
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
If I have a string how can I check if the string contains any sequence of "rldu"? I am really new to ruby, sorry if this is a stupid question to ask.
r- right, l-left, d-down, u-up.
For example:
str = "udlv" #should return false
str = "lrd" #should return true
Assuming the string should entirely be composed of the given four characters in any order
str =~ /^[rldu]+$/
will return an integer or nil that you can use in a conditional. If you want a boolean, use the trick with !!:
!!str.match(/^[rldu]+$/)
If you wanted to check whether the string contains anything other than udlr, then
!("udlv" =~ /[^udlr]/) # => false
!("lrd" =~ /[^udlr]/) # => true
This one does not use a regular expression:
p "udlv".count("^rlrd").zero? #=> false
p "lrd".count("^rldu").zero? #=> true
"^rldu" means "everything else than rldu"
Assuming that by 'any sequence of "rldu"' you mean you want to verify that the string is composed of only the r, l, d, u (any number of times, in any order) and nothing else, a good old regular expression should work just fine:
str =~ /^[udlr]*$/
If you strictly need that to be a boolean value (true/false), then you can prefix it with two exclamation points (double not), like so:
!!(str =~ /^[udlr]*$/)
In most cases, you shouldn't need to do that because Ruby can interpret any value as either true or false anyway.
You can view the documentation for all of String's core methods here. And here is a guide on regular expressions.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I need to match everything between last two '/' in a regex
for example: for string tom/jack/sam/jill/ ---> I need to match jill
and in that case also need to match tom/jack/sam (without the last '/')
Thoughts appreciated!
1)
str = "tom/jack/sam/jill/"
*the_rest, last = str.split("/")
the_rest = the_rest.join("/")
puts last, the_rest
--output:--
jill
tom/jack/sam
2)
str = "tom/jack/sam/jill/"
md = str.match %r{
(.*) #Any character 0 or more times(greedy), captured in group 1
/ #followed by a forward slash
([^/]+) #followed by not a forward slash, one or more times, captured in group 2
}x #Ignore whitespace and comments in regex
puts md[2], md[1] if md
--output:--
jill
tom/jack/sam
If what you want is given a string tom/jack/sam/jill/ extract two groups: jill and tom/jack/sam/.
The regexp you need is: ^((?:[^\/]+\/)+)([^\/]+)\/$.
Note that regexp does not accept / in the begin of string and request a / in the end of string.
Take a look: http://rubular.com/r/mxBYtC31N2