How can I update parts of the string that matches some regexp - ruby-on-rails

I have string "(1,2,3,4,5,6),(1,2,3)" I would like to change it to "('1','2','3','4','5','6'),('1','2','3')" - replase all parts that mathces /([^,)("])/ with the '$1', '$2' etc

"(1,2,3,4,5,6),(1,2,3)".gsub(/([^,)("]\w*)/,"'\\1'")
gsub is a "global replace" method in String class. It finds all occurrences of given regular expression and replaces them with the string given as the second parameter (as opposed to sub which replaces first occurrence only). That string can contain references to groups marked with () in the regexp. First group is \1, second is \2, and so on.

Try
mystring.gsub(/([\w.]+)/, '\'\1\'')
This will replace numbers (ints/floats) and words with their "quote-surrounded" selves while leaving punctuation (except the dot) alone.

UPDATED: I think you want to search for this
(([^,)("])+)
And replace it with this
'$1'
the looks for anything 1 or more times and assigns it to the $1 variable slot due to using the parenthesis around the "\d". The replace part will use what it finds as the replacement value.

Related

Difficulty applying a Regex to a Rails View. Should I make it a helper method?

I am trying to apply the following regex to one of my views:
^([^\s]+)\s+
This is to remove any string of consecutive non-whitespace characters including any white space characters that follow from the start of the line (remove everything except the first word). I have input it on Rubular and it works.
I was wondering how I would be able to apply it to my rails project. Would I create a rails helper method? So far I have tested it in irb and it is not returning the right value:
I would like to know how I can fix my method and if making it a helper method is the right approach. Thank you very much for your help guys!
The =~ operator matches the regular expression against a string, and it returns either the offset of the match from the string if it is found, otherwise nil.
You could either try it with String.match and work with the match data.
like
str.match(^([^\s]+)\s+)
or you don't use regex for readability. Split the string on spaces and return and array of the words and take the first one, like:
str.split(' ').first

Rails query by number of digits in field

I have a Rails app with a table: "clients". the clients table has a field: phone. phone data type is string. I'm using postgresql. I would like to write a query which selects all clients which have a phone value containing more than 10 digits. phone does not have a specific format:
+1 781-658-2687
+1 (207) 846-3332
2067891111
(345)222-777
123.234.3443
etc.
I've been trying variations of the following:
Client.where("LENGTH(REGEXP_REPLACE(phone,'[^\d]', '')) > 10")
Any help would be great.
You almost have it but you're missing the 'g' option to regexp_replace, from the fine manual:
The regexp_replace function provides substitution of new text for substrings that match POSIX regular expression patterns. [...] The flags parameter is an optional text string containing zero or more single-letter flags that change the function's behavior. Flag i specifies case-insensitive matching, while flag g specifies replacement of each matching substring rather than only the first one.
So regexp_replace(string, pattern, replacement) behaves like Ruby's String#sub whereas regexp_replace(string, pattern, replacement, 'g') behaves like Ruby's String#gsub.
You'll also need to get a \d through your double-quoted Ruby string all the way down to PostgreSQL so you'll need to say \\d in your Ruby. Things tend to get messy when everyone wants to use the same escape character.
This should do what you want:
Client.where("LENGTH(REGEXP_REPLACE(phone, '[^\\d]', '', 'g')) > 10")
# --------------------------------------------^^---------^^^
Try this:
phone_number.gsub(/[^\d]/, '').length

Replace a exact string using Regex in ruby

Consider the the following text
The capital asset as defined in section 2(14) is an exhaustive definition which encompasses all properties of any kind with certain exceptions but the key word is that the property should be "held" section 2.
Now I want to find section 2, for the same I have written the following Regex:
/\bsection+\.*\s+2\b/i
But it is also matching section 2 of section 2(14). I just want it to only match the exact text, not the part of text which is matching with the regex. I know I need to modify the regex, but what are the changes required?
Try with \bsection+\.*\s+2([ .,;?|!])/i . This will only match with section 2 if it is followed by a space or a punctuation mark different than (.
/\bsection+.*\s+2\b([[:punct:]]|\s/
basically you would want the word to end with whitespace or a punctuation.

How do I remove the first occurence of a substring in string?

How can I remove the first occurence of a given substring?
I have:
phrase = "foobarfoo"
and, when I call:
phrase.some_method_i_dont_know_yet ("foo")
I want the phrase to look like barfoo.
I tried with delete and slice but the first removes all the occurrences but the second just returns the slice.
Use sub! to substitute what you are trying to find with ""(nothing), thereby deleting it:
phrase.sub!("foo", "")
The !(bang) at the end makes it permanent. sub is different then gsub in that sub just substitutes the first instance of the string that you are trying to find whereas gsub finds all instances.
sub will do what you want. gsub is the global version that you're probably already familiar with.
Use the String#[] method:
phrase["foo"] = ""
For comparison, in my system this solution is 17% faster than String#sub!

Rails validates_format_of

I want to use validates_format_of to validate a comma separated string with only letters (small and caps), and numbers.
So.
example1, example2, 22example44, ex24
not:
^&*, <> , asfasfsdafas<#%$#
Basically I want to have users enter comma separated words(incl numbers) without special characters.
I'll use it to validate tags from acts_as_taggable_on. (i don't want to be a valid tag for example.
Thanks in advance.
You can always test out regular expressions at rubular, you would find that both tiftiks and Tims regular expressions work albeit with some strange edge cases with whitespace.
Tim's solution can be extended to include leading and trailing whitespace and that should then do what you want as follows :-
^\s*[A-Za-z0-9]+(\s*,\s*[A-Za-z0-9]+)*\s*$
Presumably when you have validated the input string you will want to turn it into an array of tags to iterate over. You can do this as follows :-
array_var = string_var.delete(' ').split(',')
^([a-zA-Z0-9]+,\s*)*[a-zA-Z0-9]+$
Note that this regex doesn't match values with whitespace, so it won't match multiple words like "abc xyz, fgh qwe". It matches any amount of whitespace after commas. You might not need ^ or $ if validates_format_of tries to match the whole string, I've never used Rails so I don't know about that.
^[A-Za-z0-9]+([ \t]*,[ \t]*[A-Za-z0-9]+)*$
should match a CSV line that only contains those characters, whether it's just one value or many.

Resources