how to prepend each letter with a symbol using Regex - ruby

I have a string time format like this: d-m-Y H:i. I want to format it like this: %d-%m-%Y %H:%i.
How do I prepend each letter with % using regular expressions?

This is pretty basic using String#gsub:
str = "d-m-Y H:i"
str.gsub(/[a-z]/i, '%\0')
# => "%d-%m-%Y %H:%i"
In the replacement string '%\0', \0 represents the entire match, which in this case is the matched letter, so this says, "Replace each letter with a % followed by the letter."

sorted 'd-m-Y H:i'.gsub(/[a-zA-Z]+/) { |sym| "%#{sym}" }

'd-m-Y H:i'.gsub(/(?=[a-z])/i, '%')
#=> "%d-%m-%Y %H:%i"
This reads, "replace every empty string followed by a lowercase or uppercase letter with the character '%'". (?=[a-z]) is a positive lookahead.

Related

Ruby Regular expression not matching properly

I am trying to creat a RegEx to find words that contains any vowel.
so far i have tried this
/(.*?\S[aeiou].*?[\s|\.])/i
but i have not used RegEx much so its not working properly.
for example if i input "test is 1234 and sky fly test1234"
it should match test , is, and, test1234 but showing
test, is,1234 and
if put something else then different output.
Alternatively you can also do something like:
"test is 1234 and sky fly test1234".split.find_all { |a| a =~ /[aeiou]/ }
# => ["test", "is", "and", "test1234"]
You could use the below regex.
\S*[aeiou]\S*
\S* matches zero or more non-space characters.
or
\w*[aeiou]\w*
It will solve:
\b\w*[aeiou]+\w*\b
https://www.debuggex.com/r/O-fU394iC5ErcSs7
or you can substitute \w by \S
\b\S*[aeiou]+\S*\b
https://www.debuggex.com/r/RNE6Y6q1q5yPJbe-
\b - a word boundary
\w - same as [_a-zA-Z0-9]
\S - a non-whitespace character
Try this:
\b\w*[aeiou]\w*\b
\b denotes a word boundry, so this regexp matches word bounty, zero or more letters, a vowel, zero or more letters and another word boundry

Delete all non cyrullic symbols from string

I want have a field on my form, which can contain some symbols like #, $, etc. But for another case i want to have only letters, without any symbols. How do i cut all non letter symbols and leave all russian cyrullic letters
Here is small example:
i have string "йцукен#$%йцукен"
in the end want to get "йцукен йцукен"
Try this:
'йцукен#$%йцукен'.gsub(/\P{Cyrillic}++/, ' ')
explanation:
\p{Cyrillic} is the character class for cyrillic letters.
\P{Cyrillic} contains all characters that are not cyrillic letters.
If you want to preserve other characters you can do it like this:
'123йцукен#$%йцукен456'.gsub(/[^\p{Cyrillic}0-9]++/, ' ')
brute force with a list of allowed characters
def filter(input, allowed)
input.chars.inject('') do |result, char|
result << char if allowed.include? char
result
end
end
test_string = 'abc$6&йцxyz'
allowed_characters = 'abcxyzйц'
puts filter(test_string, allowed_characters)
=> abcйцxyz
The expression "йцукен#$%йцукен" that you have in the question is not a valid Ruby expression. The #$ within double quotes works as interpolation. If you meant a string 'йцукен#$%йцукен', and if you wanted to replace sequences of characters like '#%$' with a space rather than just deleting them, then, the following can work.
'йцукен#$%йцукен'.tr('#%$', " ").squeeze(" ")
# => "йцукен йцукен"

How to find string which is started with ".."?

I was trying to find strings out which is followed by only "..",but couldn't get that :
["..ab","...cc","..ps","....kkls"].each do |x|
puts x if /../.match(x)
end
..ab
...cc
..ps
....kkls
=> ["..ab", "...cc", "..ps", "....kkls"]
["..ab","...cc","..ps","....kkls"].each do |x|
puts x if /(.)(.)/.match(x)
end
..ab
...cc
..ps
....kkls
=> ["..ab", "...cc", "..ps", "....kkls"]
Expected output:
["..ab","..ps"]
What you want is
/^\.\.(?!\.)/
The caret ^ at the beginning means match the beginning of the string; periods must be escaped by a backslash as \. because in regular expressions a plain period . matches any character; the (?!\.) is a negative look-ahead meaning the next character is not a period. So the expression means, "at the beginning of the string, match two periods, which must be followed by a character which is not a period."
>> /^\.\.(?!\.)/.match "..ab"
=> #<MatchData "..">
>> /^\.\.(?!\.)/.match "...cc"
=> nil
Try selecting on /^\.\.[^\.]/ (starts with two dots and then not a dot).
ss = ["..ab","...cc","..ps","....kkls"]
ss.select { |x| x =~ /^\.\.[^\.]/ } # => ["..ab", "..ps"]
Try using /^\.{2}\w/ as the regular expression.
A quick explanation:
^ means the start of the string. Without this, it can match dots that are found in the middle of the string.
\. translates to . -- if you use the dot on its own, it will match any non-newline character
{2} means that you're looking for two of the dots. (you could rewrite /\.{2}/ as /\.\./)
Finally, the \w matches any word character (letter, number, underscore).
A really good place to test Ruby regular expressions is http://rubular.com/ -- it lets you play with the regex and test it right in your browser.
You don't need regex for this at all, you can just extract the appropriate leading chunks using String#[] or String#slice and do simple string comparisons:
>> a = ["..ab", "...cc", "..ps", "....kkls", ".", "..", "..."]
>> a.select { |s| s[0, 2] == '..' && s[0, 3] != '...' }
=> ["..ab", "..ps", ".."]
Maybe this:
["..ab","...cc","..ps","....kkls"].each {|x| puts x if /^\.{2}\w/.match(x) }
Or if you want to make sure the . doesn't match:
["..ab","...cc","..ps","....kkls"].each {|x| puts x if /^\.{2}[^\.]/.match(x) }

Ruby: Understanding Regex

I am trying to write a script that will match all words in a string and will strip all non words (IE: . [dot], ampersands, colons, etc) out and will replace them with a hyphen.
Example String:
L. L. Cool J & Sons: The Cool Kats
Example Output:
L-L-Cool-J-Sons-The-Cool-Kats
Here is some code I am working with:
str = "L. L. Cool J & Sons: The Cool Kats"
str.scan(/\w+/)
Thanks for all the help! I am still pretty new to regex
In a single line, find all bits of text that aren't "word characters" and replace with a dash:
str.gsub(/\W+/, '-')
Note that "word characters" includes numbers and underscores. To just allow letters you could use the following:
str.gsub(/[^A-Za-z]+/, '-')
Update: I just noticed that the two calls can be expressed as one:
str.gsub(/\W+/, '-')
=> "L-L-Cool-J-Sons-The-Cool-Kats"
...which results to the same as Narendra's answer or my original answer:
# 1st gsub: replace all non-words with hyphens
# 2nd gsub: replace multiple hyphens with a single one
str.gsub(/\W/,'-').gsub(/-+/, '-')
=> "L-L-Cool-J-Sons-The-Cool-Kats"
str.gsub(/\W/, '-') #=> replaces all non-words with space
# OR
str.gsub(/[^A-Za-z\s]/, ' ') #=> replace all non letters/spaces with space
str.gsub(/\s+/, '-') #=> replaces all groups of spaces to hypens
Input:
L. L. Cool J & Sons: The Cool Kats
Output:
L-L-Cool-J-Sons-The-Cool-Kats
You can use \W for non word characters. It should do your job. \w stands for word characters. I don't work much with ruby but it should look something like this
result = subject.gsub(/\W+/, '-') .

Regex: don't match if string contains whitespace

I can't seem to figure out the regex pattern for matching strings only if it doesn't contain whitespace. For example
"this has whitespace".match(/some_pattern/)
should return nil but
"nowhitespace".match(/some_pattern/)
should return the MatchData with the entire string. Can anyone suggest a solution for the above?
In Ruby I think it would be
/^\S*$/
This means "start, match any number of non-whitespace characters, end"
You could always search for spaces, an then negate the result:
"str".match(/\s/).nil?
>> "this has whitespace".match(/^\S*$/)
=> nil
>> "nospaces".match(/^\S*$/)
=> #<MatchData "nospaces">
^ = Beginning of string
\S = non-whitespace character, * = 0 or more
$ = end of string
Not sure you can do it in one pattern, but you can do something like:
"string".match(/pattern/) unless "string".match(/\s/)
"nowhitespace".match(/^[^\s]*$/)
You want:
/^\S*$/
That says "match the beginning of the string, then zero or more non-whitespace characters, then the end of the string." The convention for pre-defined character classes is that a lowercase letter refers to a class, while an uppercase letter refers to its negation. Thus, \s refers to whitespace characters, while \S refers to non-whitespace.
str.match(/^\S*some_pattern\S*$/)

Resources