validates_format_of in rails (only numbers, commas and white spaces) - ruby-on-rails

I have a field "floors" and I want it to accept only numbers, commas and white spaces.
I'm using a validates_format_of :floors, :with => /[0-9\,\s]+/ right now, but it works bad because it accepts a string like "1, 2, abc".
Please help me to find my mistake.

Your regex matches 1, 2, inside 1, 2, abc, it is a partial match. To disallow partial matches, use start-of-string and end-of-string anchors.
In Ruby, to match the start of the string you need to use \A anchor. The end-of-string anchor is \z. Thus, use
/\A[0-9,\s]+\z/
See regex demo
Also note that , is not a special regex metacharacter and does not need escaping.
If you need to start with a number, you can use
/\A\d[\d,\s]*\z/
Here, \d will require a digit to appear in the beginning and then it can be followed with digits, whitespace and commas, zero or more occurrences. Another way of restricting the generic character class is using a lookahead: \A(?=\d)[\d,\s]+\z.
Going further, you can match numbers like 1,300,567.567 or 1 300 567.567 with
/\A\d{1,3}(?:[,\s]\d{3})*(?:\.\d+)?\z/
See another demo

Related

RegEx contain a combination of letters, numbers, and a special character

I'm finding a regular expression which adheres below rules.
Acceptance criteria: Password must contain a combination of letters, numbers, and at least a special character.`
Here is my Regex:
validates :password, presence: true,
format: { with: ^(?=[a-zA-Z0-9]*$)([^A-Za-z0-9])}
I am not all that great at regex, so any and all help is greatly appreciated!
You can use the following RegEx pattern
/^(?=.*\d)(?=.*([a-z]|[A-Z]))([\x20-\x7E]){8,}$/
Let's look at what it is doing:
(?=.*\d) shows that the string should contain atleast one integer.
(?=.*([a-z]|[A-Z])) shows that the string should contain atleast one alphabet either from downcase or upcase.
([\x20-\x7E]) shows that string can have special characters of ascii values 20 to 7E.
{8,} shows that string should be minimum of 8 characters long. While you have not mentioned it should be at least 8 characters long but it is good to have.
If you're unsure about the ASCII values, you can google it or you could use the following instead:
/^(?=.*\d)(?=.*([a-z]|[A-Z]))(?=.*[##$%^&+=]){8,}$/
As suggested in the comments, a better way can be:
/\A(?=.*\d)(?=.*([a-z]))(?=.*[##$%^&+=]){8,}\z/i
Here:
\A represents beginning of string.
\z represents end of string.
/i represents case in-sensitive mode.
P.S: I have not tested it yet. May be I'll test and update later if required.

Brakeman insufficient validation warning of regex anchors

I'm trying to implement a validation in a model like this.
validates_format_of :field, with: /[0-9]/, message: 'must have at least one number (0-9)'
Brakeman detects this a Format Validation security issue and it recommends to add the anchors between the regular expression.
Insufficient validation for 'field' using /[0-9]/. Use \A and \z as anchors near line 54
If I add those anchors, the regular expression stops working, so I don't know what to do in this case. Here's the tests I made using rails c.
"asdf1234".match(/\A[0-9]\z/) # => nil
"foobar1".match(/\A[0-9]\z/) # => nil
I need that the method return #<MatchData "1"> in both cases.
Any ideas?
Thanks.
If you need to match a string that has at least 1 digit inside, and any other chars before and after, you may use
/\A[^0-9]*[0-9].*\z/m
or just
/\A.*[0-9].*\z/m
Details
\A - start of string
[^0-9]* - zero or more chars other than an ASCII digit
[0-9] - an ASCII digit
.* - any 0+ chars, as many as possible, up to the
\z - end of string.
The m modifier makes . match any char, including a line break char.
Actually, /\A.*[0-9].*\z/m will be a bit slower, as the first .* will grab all the string at once and then will backtrack to find the last digit. The first one is more optimized.

Regex for match numbers , hypen and special characters

I have to validate below with the given condition
com.android.123foo
following conditions should be applied
Numbers shouldn't be allowed after the last dot (ex. "com.android.123foo")
NOTE: Numbers can be allowed middle or end of the string (ex. com.android.foo123 or com.adnroid.fo0123news)
special characters and hyphen should not be allowed over the entire string (ex com.android.123foo)
Kindly help.
Depending on which dot you are asking about the answer will change, but perhaps you are after something like this:
for after first dot
"com.iphones22tore.123foo".match /^.*\.[a-zA-Z.]*$/
=> nil
"com.iphonestore.foo".match /^.*\.[a-zA-Z.]*$/
=> #<MatchData "com.iphonestore.foo">
If you mean after the final dot then change the regex to:
.match /^.*\..*\.[a-zA-Z.]*$/
instead of creating a regex for a blacklist after the dot for what isnt allowed, this just simply defines what IS allowed after the dot.

Parentheses messing up validation in rails

I have the following validation:
validates_format_of :title,
:with => /^[A-Z0-9 áàâäãçéèêëíìîïñóòôøöõúùûüý'-.]*$/i,
:message => "must contain only letters, numbers, dashes, periods, and single quotes"
This works most of the time, but when a title contains an open and closed parentheses, it passes. Anyone know how to get around this or maybe there is something wrong with my validation regex?
At the end of your regular expression you have '-.
This means that you want to allow all characters between (and including) the apostrophe and the period just like you did at the beginning of the regular expression with A-Z and 0-9.
The expression /['-.]/ allows all these characters: '()*+,-.
Inside the [], you need to escape the - character. I think that this will work the way you are hoping:
/^[A-Z0-9 áàâäãçéèêëíìîïñóòôøöõúùûüý'\-.]*$/i
PS. You don't have to escape the . inside the square brackets []

username regex in rails

I am trying to find a regex to limit what a person can use for a username on my site. I don't need to have it check to see how many characters there are in it, as another validation does this. Basically all I need to make it do is make sure that it allows: letters (capital and lowercase) numbers, dashes and underscores.
I came across this: /^[-a-z]+$/i
But it doesn't seem to allow numbers.
What am I missing?
The regex you're looking for is
/\A[a-z0-9\-_]+\z/i
Meaning one or more characters of range a-z, range 0-9, - (needs to be escaped with a backslash) and _, case insensitive (the i qualifier)
Use
/\A[\w-]+\z$/
\w is shorthand for letters, digits and underscore.
\A matches at the start of the string, \z matches at the end of the string. These tokens are called anchors, and Ruby is a bit special with regard to them: Most regex engines use ^ and $ as start/end-of-string anchors by default, whereas in Ruby they can also match at the start/end of lines (which matters if you're working with multiline strings). Therefore, it's safer (as #JustMichael pointed out) to use \A and \z because there is no such ambiguity.
Your regular expression contains a character class [-a-z] that allows the characters - (dash) and a through z. In order to expand the range of characters allowed by this character class, you will need to add more characters within the [].
Please see Character Classes or Character Sets for further information and examples.

Resources