How do I split a string in ruby? [closed] - ruby

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
In my test step, I need to split letters.
find(:xpath,"//*[]").text
gives a string like "No#xyz1", where No# is a static part.
I need xyz1. How do I get that part?

String#[] with positive lookbehind comes to the rescue:
"No#xyz1"[/(?<=No#).*/]
#⇒ "xyz1"
So in your matcher you can use:
find(:xpath,"//*[]").text[/(?<=No#).*/] == "xyz1"

There are many ways to achieve that. You can, for example, use regular expression and scan method:
[1] pry(main)> "No#xyz1".scan(/No#(.+)/).first.first
=> "xyz1"
or a "dummy" split on string too:
[4] pry(main)> "No#xyz1".split("No#")
=> ["", "xyz1"]
[5] pry(main)> "No#xyz1".split("No#").last
=> "xyz1"
I would recommend the first one, though.

String#partition works fine here.
Searches sep or pattern (regexp) in the string and returns the part
before it, the match, and the part after it. If it is not found,
returns two empty strings and str.
"No#xyz1".partition("No#")
# => ["", "No#", "xyz1"]
"No#xyz1".partition("NotHere")
# => ["No#xyz1", "", ""]
So you can use :
"No#xyz1".partition("No#").last
# => "xyz1"

Related

Ruby - replace a letter for another Explanation for my code [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 months ago.
Improve this question
I got to solve the problem I was trying to solve, but the thing is that I am not sure why it worked, I just started adding methods.
So if anyone could explain why worked:
def replace(string1, letter_a, letter_b)
replacements = {letter_a => letter_b}
#this is the part I am not sure why is working:
initial_string.split('').map{|i| replacements[i] || i}.join
end
Firstly I recommend to use built-in methods String#gsub or String#tr
string.gsub(%r{#{replaceable_letter}}, replacing_letter)
"abcdef".gsub(/a/, "b") # => "bbcdef"
string.tr(replaceable_letter, replacing_letter)
"abcdef".tr("a", "b") # => "bbcdef"
Instead of initial_string.split('').map you can use initial_string.each_char.map
Explanation of your code:
replacements = {letter_a => letter_b}
is hash where replaceable letter is key and replacing letter is value
For example { "a" => "b" }
Than you split your string to chars array
After that map over this array
For every char you check the hash, for example:
replacements["a"] # => "b"
replacements["c"] # => nil
If hash has such key, you take replacing letter, if not take origin letter. Compare and read about || operator:
nil || "f" # => "f"
"b" || "a" # => "b"
And finally join new array

How would I be able to invert a string of integers? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Improve this question
I am trying to invert the string "10010" into "01101". I figured I could try to use the gsub method as shown in a similar example in the ruby documentation guides:
`"10010".gsub(/[10]/ "1" => "0", "0" => "1")` .
However this is not the case. The argument for gsub I believe is incorrect. By my logic I'm capturing an INTEGER 1 and 0 not the string, but I'm not too sure how to go about this. Is there a way to perhaps substitute the numbers such as .push/.pop and then change the integer to a string?
To change any 0 into 1, and viceversa, there is no need of gsub, the String#tr method is simpler and faster for the purpose:
'1010'.tr('10', '01')
# => "0101"
'10010'.tr('10', '01')
# => "01101"
Your approach works, you're just missing a comma:
"10010".gsub(/[01]/, "1" => "0", "0" => "1")
#=> 01101
While you can kinda use gsub, do it the right way and twiddle the bits:
("10010".to_i(2) ^ 0xff).to_s(2) # => "11101101"
Using gsub results in an incorrect answer, because 01101 is not the same as inverting the bits of an 8-bit number:
'01101'.to_i(2) # => 13
'11101101'.to_i(2) # => 237
This might help you understand what's happening:
'%08b' % 0x55 # => "01010101"
'%08b' % 0xff # => "11111111"
'%08b' % 0xaa # => "10101010"
'%08b' % (0x55 ^ 0xff) # => "10101010"
If you don't care about efficiency (as you would read the string thrice):
irb(main):004:0> puts "10010".gsub("1", "X").gsub("0", "1").gsub("X", "0")
01101
As for your approach, are you sure you aren't missing a comma?
irb(main):004:0> puts "10010".gsub("1", "X").gsub("0", "1").gsub("X", "0")
01101

Regex without order [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Suppose I have a list of characters [a,b,c] and I want to write a regular expression such that
any string is accepted if it has all the elements in the character list at-least once and the characters can appear in any order in the string.
Example of accepted strings
abc, aabbbc, bbaac, cab
Example of strings not accepteed
aaabb, bab, caa, aacd, deeff
Sets are much more suited for this purpose than regular expressions. What you're really trying to do is find out if (a, b, c) is a valid subset of your various strings. Here's an example of how to do that in Ruby:
> require "set"
=> true
> reference = Set.new("abc".split(""))
=> #<Set: {"a", "b", "c"}>
> test1 = Set.new("aabbbc".split(""))
=> #<Set: {"a", "b", "c"}>
> test2 = Set.new("caa".split(""))
=> #<Set: {"c", "a"}>
> reference.subset? test1
=> true
> reference.subset? test2
=> false
Consider this before reading on: regexes are not always the best way to solve a problem. If you are considering a regex but it's not obvious or easy to proceed, you may want to stop and consider if there is an easy non-regex solution handy.
I don't know what your specific situation is or why you think you need regex, so I'll assume you already know the above and answer your question as-is.
Based on the documentation, I beleive that Ruby supports positive lookaheads (also known as zero-width assertions). Being primarily a .NET programmer, I don't know Ruby well enough to say whether or not it supports non-fixed-length lookaheads (it's not found in all regex flavors), but if it does then you can easily apply three different lookaheads at the beginning of your expression to find each of the patterns or characters you need:
^(?=.*a)(?=.*b)(?=.*c).*
This will fail if any one of the lookaheads does not pass. This approach is potentially extremely powerful because you can have complex sub expressions in your lookahead. For example:
^(?=.*a[bc]{2})(?=.*-\d)(?=.*#.{3}%).*
will test that the input contains an a follwed by two characters which are each either a b or a c, a - followed by any digit and a # followed by any three characters followed by a %, in any particular order. So the following strings would pass:
#acb%-9
#-22%abb
This kind of complex pattern matching is difficult to succinctly duplicate.
To address this comment:
No there cannot be... so abcd is not accepted
You can use a negative lookahead to ensure that characters other than the desired characters are not present in the input:
^(?=.*a)(?=.*b)(?=.*c)(?!.*[^abc]).*
(As noted by Gene, the .* at the end is not necessary... I probably should have mentioned that. It's just there in case you actually want to select the text)
def acceptable? s
s =~ /(?=.*a)(?=.*b)(?=.*c)/
end
acceptable? 'abc' # => 0
acceptable? 'aabbbc' # => 0
acceptable? 'bbaac' # => 0
acceptable? 'cab' # => 0
acceptable? 'aaabb' # => nil
acceptable? 'bab' # => nil
acceptable? 'caa' # => nil
acceptable? 'aacd' # => nil
acceptable? 'deeff' # => nil
acceptable? 'abcd' # => 0
A regex that matches only the defined characters could be this:
(?=[bc]*a)(?=[ac]*b)(?=[ab]*c)[abc]*

Check whether string contains a full word [closed]

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
Is there something in Ruby that returns true only if the string contains the whole word, in this case 'hello'?
I don't want the behavior of include? which returns true if only some characters within a word are present:
'hello whats up'.include? 'll'
=> true
> 'hownowbrowncow'['now'] => "now" # will be nil if not found
And if you want it to require word boundaries...
'hownowbrowncow'[/\bnow\b/] => nil
It doesn't really matter if it returns true or false, since anything other than nil or false will fulfill a conditional test. If you really like true and false, well, you can turn an arbitrary expression into true or false a number of ways, one way is:
'now'.nil? => false
!'now'.nil? => true
Lots of good ways to do this as others have given. Here's another way:
my_string.scan(/\w+/).include? "hello"
This would be a case-sensitive check. For case insensitive:
my_string.scan(/\w+/).map(&:downcase).include? "hello"
This will also work with a variable for "hello":
m_string.scan(/\w+/).map(&:downcase).include? my_word
str = "Hello guys, how are you?'"
keyword = "hello"
print str.split.map { |word| word.downcase }.include? keyword.downcase
If you mean only the alphabet, then you could
(! 'Wr4ngle'.gsub(/[A-Za-z]/, '').blank?)
That grep should be versatile enough for your needs
It sounds like you're asking to simply do:
"hello" == "hello"
If you don't want the match to be case sensitive, you could use:
"HeLlO".downcase == "hElLo".downcase
If you are looking to see if a string of characters includes another string of characters, you could do something like this:
s1 = "hello"
s2 = "oelhl"
s1.split("").sort == s2.split("").sort #=> case sensitive
s1.downcase.split("").sort == s2.downcase.split("").sort #=> not case sensitive

Ruby split on numbers vs letters

I'd like to split the following string on letters:
1234B
There are always only ever 4 digits and one letter. I just want to split those out.
Here is my attempt, I think I have the method right and the regex matches the number but I dont think my syntax or my regex is pertinent to the problem Im attempting to solve.
"1234A".split(/^\d{4}/)
What you want is not clear, but a general solution to this kind of situation is:
"1234A".scan(/\d+|\D+/)
# => ["1234", "A"]
If there are always 4 digits and 1 letter, there's no need to use regular expressions to split the string. Just do this:
str = "1234A"
digits,letter = str[0..3],str[4]
Looking at it purely from the perspective of splitting any string into groups of 4:
"1234A".scan(/.{1,4}/)
# => ["1234", "A"]
Another no-regex version:
str = "1234A"
str.chars.to_a.last # => "A"
str.chop # => "1234"

Resources