I have the following working gsheet formula that transposes, split, trims using REGEXEXTRACT which works to capture the first group of strings separated by OR
=transpose(split(IFERROR(TRIM(REGEXEXTRACT(A2,"([^\()]+)")))," OR ",FALSE))
Example below using formula above
("AD" OR "AB" OR "ZZ" OR "Short Long" OR "Long Short") w/5 (("foo bar*" OR "bar* foo" OR "kit kat*") w/5 ("ping* pong game*" OR "ppg") w/5 ("bro" OR "sis" OR "fam"))
extracts the following for group 1
"AD"
"AB"
"ZZ"
"Short Long"
"Long Short"
How to extract other groups that are in between w/5 string? Note that there can be multiple instances of w/5 from a given statement. Example above have 3.
Expected output group 2
"foo bar*"
"bar* foo"
"kit kat*"
Expected output group 3
"ping* pong game*"
"ppg"
Expected output group 4
"bro"
"sis"
"fam"
Let me know if this works for you!
=TRANSPOSE(INDEX(SPLIT(INDEX(REGEXEXTRACT(TRANSPOSE(split(A2," w/5 ",FALSE)),"([^\()]+)"))," OR ",false)))
Related
I want to be able to copy and paste a large string of words from say a text document where there are spaces, returns and not commas between each and every word. Then i want to be able to take out each word individually and put them in a table for example...
input:
please i need help
output:
{1, "please"},
{2, "i"},
{3, "need"},
{4, "help"}
(i will have the table already made with the second column set to like " ")
havent tried anything yet as nothing has come to mind and all i could think of was using gsub to turn spaces into commas and find a solution from there but again i dont think that would work out so well.
Your delimiters are spaces ( ), commas (,) and newlines (\n, sometimes \r\n or \r, the latter very rarely). You now want to find words delimited by these delimiters. A word is a sequence of one or more non-delimiter characters. This trivially translates to a Lua pattern which can be fed into gmatch. Paired with a loop & inserting the matches in a table you get the following:
local words = {}
for word in input:gmatch"[^ ,\r\n]+" do
table.insert(words, word)
end
if you know that your words are gonna be in your locale-specific character set (usually ASCII or extended ASCII), you can use Lua's %w character class for matching sequences of alphanumeric characters:
local words = {}
for word in input:gmatch"%w+" do
table.insert(words, word)
end
Note: The resulting table will be in "list" form:
{
[1] = "first",
[2] = "second",
[3] = "third",
}
(for which {"first", "second", "third"} would be shorthand)
I don't see any good reasons for the table format you have described, but it can be trivially created by inserting tables instead of strings into the list.
I'm using Rails 5. I'm having an issue writing a regular expression. I want to write an expression that will parse a string, looking for a positive number and then the first word that follows the number, whether or not there's a space or other type of word boundary between the number and the next word. So I tried
2.4.0 :006 > str = "2g"
=> "2g"
2.4.0 :007 > str.match(/\W?(([0-9]+(\.[0-9]+)?)\W*(^[0-9:\/]+))/)
=> nil
but as you can see no matches occur. I would expect the match to capture the "2" and then the "g". Similarly, if I have a string like
2.4.0 :008 > str = "12.2 word next"
=> "12.2 word next"
2.4.0 :009 > str.match(/\W?(([0-9]+(\.[0-9]+)?)\W*(^[0-9:\/]+))/)
=> nil
I expect the regex to capture the "12.2" and then the next word "word". But as you can see my regex isn't cutting it. How do I fix it to capture what I need?
Are you trying to select "12.2word" or "12.2 word" in "12.2 word next" ?
As you replied in comments, to have float number in group1 and word in group2:
(\d+\.\d+|\d+)[^a-zA-Z0-9]*([a-zA-Z]+)
Full match 6-15 `12.2 good`
Group 1. 6-10 `12.2`
Group 2. 11-15 `good`
My first Answer was:
(\d+(\.\d{0,})?)[^a-zA-Z0-9]*([a-zA-Z]+)
for " 12.2 good "
Full match 6-15 `12.2 good`
Group 1. 6-10 `12.2`
Group 2. 8-10 `.2`
Group 3. 11-15 `good`
Group1 is your integer part and Group2 is null or equal to .2 in this example.
This Should Work.
([0-9.]+)\s(\w+)
Input:
12.2 word
Output:
12.2
word
Ruby Code:
re = /([0-9.]+)\s(\w+)/
str = '12.2 word'
# Print the match result
str.scan(re) do |match|
puts match.to_s
end
See: https://regex101.com/r/ncVEAT/1
I'm writing little Rails api application, and I need to analyze string to find words having given string like:
Assuming my source text is hello mr one two three four nine nineteen and I want to check occurence of on, it will produce: one, and if I'll check occurence of ne t in the same string it will result in one two.
I know there is an ugly way with substrings, counting positions and parsing string this way, but I think it can be solved with regex scan.
Please say if you need some additional information, thanks.
▶ str = 'hello mr one two three four nine nineteen'
#⇒ "hello mr one two three four nine nineteen"
▶ re = ->(pattern) { /\p{L}*#{pattern}\p{L}*/ }
▶ str[re.('ne t')]
#⇒ "one two"
▶ str[re.('on')]
#⇒ "one"
Matcher \p{L} is generally better than \w and, especially, \S because it matches all utf-8 letters.
To match accented letters as well (i. e. combined ï in “naïve”,) one should extend left and right matchers:
▶ re = ->(pattern) { /[\p{L}\p{Mc}]*#{pattern}[\p{L}\p{Mc}]*/ }
Please note, that code above will return the first match. To return all matches, use String#scan instead of String#[]:
▶ str.scan re.('ni')
#⇒ ["nine", "nineteen"]
Use a regular expression:
search = "on"
/\s([^\s]*#{search}.[^\s]*)\s/.match("hello mr one two three four nine nineteen")[1]
# returns "one"
search = "ne t"
/\s([^\s]*#{search}.[^\s]*)\s/.match("hello mr one two three four nine nineteen")[1]
# returns "one two"
The way it works is it finds the substring you are looking for, and then groups any additional characters that are attached to the ends of your substring stopping at the first whitespace on both ends.
I am using Ruby on Rails v3.0.9 and I would like to "transform" an array of strings in a sentence including punctuation. That is, if I have an array like the following:
["element 1", "element 2", "element 3"]
I would like to get\build:
# Note: I added 'Elements are: ' at the begin, ',' between elements and '.' at
# the end.
"Elements are: element 1, element 2, element 3."
How can I do that?
Rails has Array#to_sentence that will do the same as array.join(', ') and additionally add "and " before the last item.
puts "Elements are: #{["element 1", "element 2", "element 3"].to_sentence}."
The rest, as you can see, is just putting it together.
#coreyward's answer is close, but his suggestion's output doesn't match the requested output. This will give you exactly what you want:
puts "Elements are: #{array.to_sentence(last_word_connector: ', ')}."
See the docs for more examples and options.
Is there anything better than string.scan(/(\w|-)+/).size (the - is so, e.g., "one-way street" counts as 2 words instead of 3)?
string.split.size
Edited to explain multiple spaces
From the Ruby String Documentation page
split(pattern=$;, [limit]) → anArray
Divides str into substrings based on a delimiter, returning an array
of these substrings.
If pattern is a String, then its contents are used as the delimiter
when splitting str. If pattern is a single space, str is split on
whitespace, with leading whitespace and runs of contiguous whitespace
characters ignored.
If pattern is a Regexp, str is divided where the pattern matches.
Whenever the pattern matches a zero-length string, str is split into
individual characters. If pattern contains groups, the respective
matches will be returned in the array as well.
If pattern is omitted, the value of $; is used. If $; is nil (which is
the default), str is split on whitespace as if ' ' were specified.
If the limit parameter is omitted, trailing null fields are
suppressed. If limit is a positive number, at most that number of
fields will be returned (if limit is 1, the entire string is returned
as the only entry in an array). If negative, there is no limit to the
number of fields returned, and trailing null fields are not
suppressed.
" now's the time".split #=> ["now's", "the", "time"]
While that is the current version of ruby as of this edit, I learned on 1.7 (IIRC), where that also worked. I just tested it on 1.8.3.
I know this is an old question, but this might be useful to someone else looking for something more sophisticated than string.split. I wrote the words_counted gem to solve this particular problem, since defining words is pretty tricky.
The gem lets you define your own custom criteria, or use the out of the box regexp, which is pretty handy for most use cases. You can pre-filter words with a variety of options, including a string, lambda, array, or another regexp.
counter = WordsCounted::Counter.new("Hello, Renée! 123")
counter.word_count #=> 2
counter.words #=> ["Hello", "Renée"]
# filter the word "hello"
counter = WordsCounted::Counter.new("Hello, Renée!", reject: "Hello")
counter.word_count #=> 1
counter.words #=> ["Renée"]
# Count numbers only
counter = WordsCounted::Counter.new("Hello, Renée! 123", rexexp: /[0-9]/)
counter.word_count #=> 1
counter.words #=> ["123"]
The gem provides a bunch more useful methods.
If the 'word' in this case can be described as an alphanumeric sequence which can include '-' then the following solution may be appropriate (assuming that everything that doesn't match the 'word' pattern is a separator):
>> 'one-way street'.split(/[^-a-zA-Z]/).size
=> 2
>> 'one-way street'.split(/[^-a-zA-Z]/).each { |m| puts m }
one-way
street
=> ["one-way", "street"]
However, there are some other symbols that can be included in the regex - for example, ' to support the words like "it's".
This is pretty simplistic but does the job if you are typing words with spaces in between. It ends up counting numbers as well but I'm sure you could edit the code to not count numbers.
puts "enter a sentence to find its word length: "
word = gets
word = word.chomp
splits = word.split(" ")
target = splits.length.to_s
puts "your sentence is " + target + " words long"
The best way to do is to use split method.
split divides a string into sub-strings based on a delimiter, returning an array of the sub-strings.
split takes two parameters, namely; pattern and limit.
pattern is the delimiter over which the string is to be split into an array.
limit specifies the number of elements in the resulting array.
For more details, refer to Ruby Documentation: Ruby String documentation
str = "This is a string"
str.split(' ').size
#output: 4
The above code splits the string wherever it finds a space and hence it give the number of words in the string which is indirectly the size of the array.
The above solution is wrong, consider the following:
"one-way street"
You will get
["one-way","", "street"]
Use
'one-way street'.gsub(/[^-a-zA-Z]/, ' ').split.size
This splits words only on ASCII whitespace chars:
p " some word\nother\tword|word".strip.split(/\s+/).size #=> 4