Return first match of Ruby regex
You could try String#[]
(as in variableName[/regular expression/]
).
This is an example output from IRB:
names = "erik kalle johan anders erik kalle johan anders"
# => "erik kalle johan anders erik kalle johan anders"
names[/kalle/]
# => "kalle"
How to return first match sub-string of a string using Ruby regex?
scan
will return all substrings that matches the pattern. You can use match
, scan
or []
to achieve your goal:
report_path = '/usr/share/filebeat/reports/ui/local/20200904_151507/API/API_Test_suite/20200904_151508/20200904_151508.csv'
report_path.match(/\d{8}_\d{6}/)[0]
# => "20200904_151507"
report_path.scan(/\d{8}_\d{6}/)[0]
# => "20200904_151507"
# String#[] supports regex
report_path[/\d{8}_\d{6}/]
# => "20200904_151507"
Note that match
returns a MatchData
object, which may contains multiple matches (if we use capture groups). scan
will return an Array
containing all matches.
Here we're calling [0]
on the MatchData
to get the first match
Capture groups:
Regex allow us to capture multiples substring using one patern. We can use ()
to create capture groups. (?'some_name'<pattern>)
allow us to create named capture groups.
report_path = '/usr/share/filebeat/reports/ui/local/20200904_151507/API/API_Test_suite/20200904_151508/20200904_151508.csv'
matches = report_path.match(/(\d{8})_(\d{6})/)
matches[0] #=> "20200904_151507"
matches[1] #=> "20200904"
matches[2] #=> "151507"
matches = report_path.match(/(?'date'\d{8})_(?'id'\d{6})/)
matches[0] #=> "20200904_151507"
matches["date"] #=> "20200904"
matches["id"] #=> "151507"
We can even use (named) capture groups with []
From String#[]
documentation:
If a Regexp is supplied, the matching portion of the string is returned. If a capture follows the regular expression, which may be a capture group index or name, follows the regular expression that component of the MatchData is returned instead.
report_path = '/usr/share/filebeat/reports/ui/local/20200904_151507/API/API_Test_suite/20200904_151508/20200904_151508.csv'
# returns the full match if no second parameter is passed
report_path[/(\d{8})_(\d{6})/]
# => 20200904_151507
# returns the capture group n°2
report_path[/(\d{8})_(\d{6})/, 2]
# => 151507
# returns the capture group called "date"
report_path[/(?'date'\d{8})_(?'id'\d{6})/, 'date']
# => 20200904
How do I find the first occurrence of a regex in Ruby?
You may use
first_occurrence = s =~ /regex/
If the result is not nil
, it contains the index of the first match. See the Ruby demo.
See Ruby 2.4 documentation:
=~
is Ruby's basic pattern-matching operator. ... If a match is found, the operator returns index of first match in string, otherwise it returnsnil
.
Ruby str.match(regex) returns MatchData containing only first matched item
It seems that MatchData
returned by .match()
method only returns the first match with all captured groups if any. I have just tested it and I only could get 1 match with .match()
.
See Regular-Expressions.info details:
To test if a particular regex matches (part of) a string, you can
either use the =~ operator, call the regexp object's match() method,
e.g.: print "success" if subject =~ /regex/ or print "success" if
/regex/.match(subject).
Also, from here:
String.=~(Regexp)
returns the starting position of the first match or
nil if no match was found
To obtain all matches, you need to use .scan()
method.
Ruby - How to return matched Regexp value
Try with this
pattern = Regexp.union(['+', '-']) #=> /\+|\-/
using operator
['foo', '+', 'bar'].select{ |e| e =~ pattern }
=>["+"]
using match? method
['foo', '+', 'bar'].select{ |e| e.match?(pattern)
=>["+"]
using String#[]
['foo', '+', 'bar'].select{ |e| e[pattern] }
=>["+"]
RegExp#match returns only one match
You need to use .scan()
to match more than once:
p s.scan(/a/).to_a
And with grouping, you get one result for the overall match, and one for each group (when using .match()
. Both results are the same in your regex.
Some examples:
> /(a)/.match(s).to_a
=> ["a", "a"] # First: Group 0 (overall match), second: Group 1
> /(a)+/.match(s).to_a
=> ["aaaa", "a"] # Regex matches entire string, group 1 matches the last a
> s.scan(/a/).to_a
=> ["a", "a", "a", "a"] # Four matches, no groups
> s.scan(/(a)/).to_a
=> [["a"], ["a"], ["a"], ["a"]] # Four matches, each containing one group
> s.scan(/(a)+/).to_a
=> [["a"]] # One match, the last match of group 1 is retained
> s.scan(/(a+)(a)/).to_a
=> [["aaa", "a"]] # First group matches aaa, second group matches final a
> s.scan(/(a)(a)/).to_a
=> [["a", "a"], ["a", "a"]] # Two matches, both group participate once per match
Regex match everything up to first period
/^([^.]+)/
Let's break it down,
^
is the newline anchor[^.]
this matches any character that's not a period\+
to take until a period
And the expression is encapsulated with () to capture it.
Ruby expression to return first x letters and also first word
You don't need to use regular expression.
def first_letters(str, num)
str[0, num]
end
def first_word(str)
str.split[0]
end
Using regular expression:
def first_letters(str, num)
str[Regexp.new("^.{#{num}}")]
end
def first_word(str)
str[/\w+/] # or str[/\S+/]
end
Ruby Regex: Match Until First Occurance of Character
You're missing the ?
quantifier to make it a non greedy match. And I would remove |
from inside of your character class because it's trying to match a single character in the list (#|@
) literally.
/-\s(.*?)(?=[#@])/
See Demo
You really don't need a Positive Lookahead here either, just match up until those characters and print the result from your capturing group.
/-\s(.*?)[#@]/
You could also use negation in this case.
/-\s([^#@]*)/
Ruby: Find first N regex matches in a string (and stop scanning)
Not that elegant, but you could use the block form:
str = 'abcabcabc'
result = []
str.scan(/b/) { |match| result << match; break if result.size >= 2 }
result #=> ["b", "b"]
Related Topics
Difference Between Truncation, Transaction and Deletion Database Strategies
Bundle Failing - Can't Find the Postgresql Client Library (Libpq)
Ruby Craziness: Class VS Object
How to Build a Rubygems Mirror Server
Parsing Xls and Xlsx (Ms Excel) Files with Ruby
How (Replace|Create) an Enum Field on Rails 2.0 Migrations
Macos Mojave 'Ruby/Config.H' File Not Found
Error While Installing Nokogiri (1.6.7) on El Capitan
How to Set Up Simple Http Authentication for a Ruby on Rails App on Heroku
Rails: Should Partials Be Aware of Instance Variables
Devise Logged in Root Route Rails 3
How to Get the Class of a Basicobject Instance
Why Do This Ruby Object Have Both To_S and Inspect Methods That Appear to Do the Same Thing
Project Euler 1:Find the Sum of All the Multiples of 3 or 5 Below 1000