For example: there has a string:
'Trump is great#Trump is great#'
If I do:
'Trump is great#Trump is great#'.delete! 'Trump is great#'
I will get:
''
But I want to get:
'Trump is great#'
So I want to a range of 'Trump is great#', and delete this substring by this range.
How to do that?
Or other ways to delete a substring?
I think what you are looking for is sub!.
Unlike gsub! or delete!, it only replaces the first match.
'Trump is great#Trump is great#'.sub!('Trump is great#', '')
=> 'Trump is great#'
Since it accepts regular expressions, you could use gsub to define how many times you would like for it to match.
If your string is always doubled...
str.gsub!(/^(.*)(?=\1$)/, '')
I find I can do this! :
'Trump is great#Trump is great#'.slice! 'Trump is great#'
If the pattern of your string is similar, you can do something like:
string.split('#').first + '#'
You can also add a custom method to string Class:
class String
def cut_pound
split('#').first + '#'
end
end
So, in case you are having strings with same pattern:
string1 = 'Wimbledon Open#Wimbledon Open#'
string2 = 'FIFA world cup#FIFA world cup#'
Is it possible to call:
string1.cut_pound # => "Wimbledon Open#"
string2.cut_pound # => "FIFA world cup#"
You can remove the pound getting rid of + '#'
Related
I am new to ruby and I want to do the following action to remove last "_val3" in ruby:
$ val="val1_val2_val3"
$ echo ${val%_*}
val1_val2
I used to use echo ${val%_*} to get "val1_val2", but i do not how do this in ruby.
Also, how to get "val1"?
Is there a good way to do them?
Not a ruby expert but I'll get the ball rolling with a regular expression:
a.sub /_[^_]*$/, ''
Match an underscore followed by any number of non-underscores at the end of the string. Replace with nothing.
You can use a single gsub to get your expected o/p,
a = "a-b_c_d"
# => "a-b_c_d"
a.gsub /_[a-z]*$/, ''
# => "a-b_c"
Or, you can use ruby split and join,
a.split("_")[0..-2].join("_")
# => "a-b_c"
String#rpartition would probably work:
'a-b_c_d'.rpartition('_') #=> ["a-b_c", "_", "d"]
rpartition looks for the last '_' and returns an array containing the part before it, the separator itself and the part after it.
I am trying to use gsub or sub on a regex passed through terminal to ARGV[].
Query in terminal: $ruby script.rb input.json "\[\{\"src\"\:\"
Input file first 2 lines:
[{
"src":"http://something.com",
"label":"FOO.jpg","name":"FOO",
"srcName":"FOO.jpg"
}]
[{
"src":"http://something123.com",
"label":"FOO123.jpg",
"name":"FOO123",
"srcName":"FOO123.jpg"
}]
script.rb:
dir = File.dirname(ARGV[0])
output = File.new(dir + "/output_" + Time.now.strftime("%H_%M_%S") + ".json", "w")
open(ARGV[0]).each do |x|
x = x.sub(ARGV[1]),'')
output.puts(x) if !x.nil?
end
output.close
This is very basic stuff really, but I am not quite sure on how to do this. I tried:
Regexp.escape with this pattern: [{"src":".
Escaping the characters and not escaping.
Wrapping the pattern between quotes and not wrapping.
Meditate on this:
I wrote a little script containing:
puts ARGV[0].class
puts ARGV[1].class
and saved it to disk, then ran it using:
ruby ~/Desktop/tests/test.rb foo /abc/
which returned:
String
String
The documentation says:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\d' will match a backlash followed by ādā, instead of a digit.
That means that the regular expression, though it appears to be a regex, it isn't, it's a string because ARGV only can return strings because the command-line can only contain strings.
When we pass a string into sub, Ruby recognizes it's not a regular expression, so it treats it as a literal string. Here's the difference in action:
'foo'.sub('/o/', '') # => "foo"
'foo'.sub(/o/, '') # => "fo"
The first can't find "/o/" in "foo" so nothing changes. It can find /o/ though and returns the result after replacing the two "o".
Another way of looking at it is:
'foo'.match('/o/') # => nil
'foo'.match(/o/) # => #<MatchData "o">
where match finds nothing for the string but can find a hit for /o/.
And all that leads to what's happening in your code. Because sub is being passed a string, it's trying to do a literal match for the regex, and won't be able to find it. You need to change the code to:
sub(Regexp.new(ARGV[1]), '')
but that's not all that has to change. Regexp.new(...) will convert what's passed in into a regular expression, but if you're passing in '/o/' the resulting regular expression will be:
Regexp.new('/o/') # => /\/o\//
which is probably not what you want:
'foo'.match(/\/o\//) # => nil
Instead you want:
Regexp.new('o') # => /o/
'foo'.match(/o/) # => #<MatchData "o">
So, besides changing your code, you'll need to make sure that what you pass in is a valid expression, minus any leading and trailing /.
Based on this answer in the thread Convert a string to regular expression ruby, you should use
x = x.sub(/#{ARGV[1]}/,'')
I tested it with this file (test.rb):
puts "You should not see any number [0123456789].".gsub(/#{ARGV[0]}/,'')
I called the file like so:
ruby test.rb "\d+"
# => You should not see any number [].
I have a string which looks like:
hello/world/1.9.2-some-text
hello/world/2.0.2-some-text
hello/world/2.11.0
Through regex I want to get the string after last '/' and until end of line i.e. in above examples output should be 1.9.2-some-text, 2.0.2-some-text, 2.11.0
I tried this - ^(.+)\/(.+)$ which returns me an array of which first object is "hello/world" and 2nd object is "1.9.2-some-text"
Is there a way to just get "1.9.2-some-text" as the output?
Try using a negative character class ([^ā¦]) like this:
[^\/]+$
This will match one or more of any character other than / followed by the end of the string.
You can use a negated match here.
'hello/world/1.9.2-some-text'.match(Regexp.new('[^/]+$'))
# => "1.9.2-some-text"
Meaning any character except: / (1 or more times) followed by the end of the string.
Although, the simplest way would be to split the string.
'hello/world/1.9.2-some-text'.split('/').last
# => "1.9.2-some-text"
OR
'hello/world/1.9.2-some-text'.split('/')[-1]
# => "1.9.2-some-text"
If you do not need to use a regex, the ordinary way of doing such thing is:
File.basename("hello/world/1.9.2-some-text")
#=> "1.9.2-some-text"
This is one way:
s = 'hello/world/1.9.2-some-text
hello/world/2.0.2-some-text
hello/world/2.11.0'
s.lines.map { |l| l[/.*\/(.*)/,1] }
#=> ["1.9.2-some-text", "2.0.2-some-text", "2.11.0"]
You said, "in above examples output should be 1.9.2-some-text, 2.0.2-some-text, 2.11.0". That's neither a string nor an array, so I assumed you wanted an array. If you want a string, tack .join(', ') onto the end.
Regex's are naturally "greedy", so .*\/ will match all characters up to and including the last / in each line. 1 returns the contents of the capture group (.*) (capture group 1).
I have strings like these:
asdf.123
asdf_123
asdf123
as123df
How could I split by any non-letter character to get this:
asdf
asdf
asdf
as
You could use the String#[] method:
regexp = /^[a-z]+/i
'asdf.123'[regexp]
# => "asdf"
'as123df'[regexp]
# => "as"
'ASas123'[regexp]
# => "ASas"
"your string".split(/[^A-Za-z]/).first
Will split by anything not in A-Z or a-z and then return the first result.
You could simply just replace all non-alpha characters using gsub(/\W+/, '') with a regex expression...
You could simply do:
a = "string 1232"
a[/[a-zA-Z]+/]
# => "string"
This will work for you "aaas._123ff".gsub!(/[^a-zA-Z].*/, '')
=> "aaas"
How do I remove a substring after a certain character in a string using Ruby?
new_str = str.slice(0..(str.index('blah')))
I find that "Part1?Part2".split('?')[0] is easier to read.
I'm surprised nobody suggested to use 'gsub'
irb> "truncate".gsub(/a.*/, 'a')
=> "trunca"
The bang version of gsub can be used to modify the string.
str = "Hello World"
stopchar = 'W'
str.sub /#{stopchar}.+/, stopchar
#=> "Hello W"
A special case is if you have multiple occurrences of the same character and you want to delete from the last occurrence to the end (not the first one).
Following what Jacob suggested, you just have to use rindex instead of index as rindex gets the index of the character in the string but starting from the end.
Something like this:
str = '/path/to/some_file'
puts str.slice(0, str.index('/')) # => ""
puts str.slice(0, str.rindex('/')) # => "/path/to"
We can also use partition and rpartitiondepending on whether we want to use the first or last instance of the specified character:
string = "abc-123-xyz"
last_char = "-"
string.partition(last_char)[0..1].join #=> "abc-"
string.rpartition(last_char)[0..1].join #=> "abc-123-"