Rails: Regex for lastname or firstname in rails - ruby-on-rails

I know that this question is over asked, but I couldn't find something that fits in my case and also works with rails. I'm looking for a simple regex for words that can contain:
letters(no digits)
white spaces
. (dot) or - (dash)

The following regex allows letters, white space, dot and dash:
/[a-z\s.-]/i
Your validation in model would be:
validates_format_of :first_name, :with => /[a-z\s.-]/i

Just to add to Sharvy Ahmed's answer.
You can also represent the validation in this format in the model
Define the Regex as a constant and then reference it in the first_name validation.
validates :first_name, format: { with: VALID_NAME_REGEX }
VALID_NAME_REGEX = /[a-z\s.-]/i
Where:
/ - Indicates the start of a new character
a-z - Matches characters in the range 'a' to 'z'
\s - Matches any whitespace character like tabs, spaces
. - Matches a '.' character
- - Matches a '-' character
/i - Makes the whole expression case insensitive.
That's all.
I hope this helps

Related

Regex to check if string is just made up of special characters

I have some strings for which i have to check whether it is made up of all special characters in regex i tried something but its not working the way i want any help ?
str = "##%^"
regex = /[\?\<\>\'\,\?\[\]\}\{\=\-\)\(\*\&\^\%\$\#\`\~\{\}\#]/
str.match(regex)
You can do it with
/\A\W*\z/
The \W* matches any non-word character from the beginning (\A) till the end (\z) of string.
See demo:
class String
def onlySpecialChars?
!!self.match(/\A\W*\z/)
end
end
puts "##%^".onlySpecialChars? # true
puts "w##%^".onlySpecialChars? # false
If you have your own set of special characters, just use instead of \W. Just also note you have overescaped your regex, [?<>',?\[\]}{=)(*&^%$#`~{}#-] will suffice.

Rails regex validation failing in rspec

I am trying to write and test a regex valiation which allows only for a sequence of paired integers, in the format
n,n n,n
where n is any integer not beginning with zero and pairs are space separated. There may be a single pair or the field may also be empty.
So with this data, it should give 2 errors
12,2 11,2 aa 111,11,11
error 1: the 'aa'
error 2: the triplet (111,11,11)
In my Rails model I have this
validates_format_of :sequence_excluded_region, :sequence_included_region,
with: /[0-9]*,[0-9] /, allow_blank: true
In my Rspec model test I have this
it 'is invalid with alphanumeric SEQUENCE_INCLUDED_REGION' do
expect(DesignSetting.create!(sequence_included_region: '12,2 11,2 aa 111,11,11')).to have(1).errors_on(:sequence_included_region)
end
The test fails, as the regex does not find the errors, or perhaps I am calling the test incorrectly.
Failures:
1) DesignSetting is invalid with alphanumeric SEQUENCE_INCLUDED_REGION
Failure/Error: expect(DesignSetting.create!(sequence_included_region: '12,2 11,2 aa 111,11,11')).to have(2).errors_on(:sequence_included_region)
expected 2 errors on :sequence_included_region, got 0
# ./spec/models/design_setting_spec.rb:5:in `block (2 levels) in <top (required)>'
Regex
Your regex matches a single pair followed by a space anywhere in the string.
'12,2 11,2 aa 111,11,11 13,3'.scan /[0-9]*,[0-9] /
=> ["12,2 ", "11,2 "]
So any string with one valid pair followed by a space will be valid. Also a single pair would fail 3,4 as there is no space.
A regex that would validate the entire string:
positive_int = /[1-9][0-9]*/
pair = /#{positive_int},#{positive_int}/
re_validate = /
\A # Start of string
#{pair} # Must have one number pair.
(?:\s#{pair})* # Can be followed by any number of pairs with a space delimiter
\z # End of string (no newline)
/x
Validators
I don't use rails much but it seems like you are expecting too much from a simple regex validator for it to parse out the individual error components from a string for you.
If you split the variable up by space and then validated each element of the array you could get that detail for each field.
'12,2 11,2 aa 111,11,11 13,3'.split(' ').reject{|f| f =~ /^[1-9][0-9]*,[1-9][0-9]*$/ }
You can put something like that into a custom validator class using validates_with which you can then have direct control of your errors with...
class RegionValidator < ActiveModel::Validator
def validate(record)
record.sequence_included_region.split(' ').reject{|f| f =~ /^[1-9][0-9]*,[1-9][0-9]*$/ }.each do |err|
record.errors[sequence_included_region] << "bad region field [#{err}]"
end
end
end
(?<=\s|^)\d+,\d+(?=\s|$)
Try this.Replace with empty string.The left string split by are your errors.
See demo.
http://regex101.com/r/rQ6mK9/22

How to remove "$" and "," from a price field in Rails

I am saving a price string to my database in a decimal-type column.
The price comes in like this "$ 123.99" which is fine because I wrote a bit of code to remove the "$ ".
However, I forgot that the price may include a comma, so "$ 1,234.99" breaks my code. How can I also remove the comma?
This is my code to remove dollar sign and space:
def price=(price_str)
write_attribute(:price, price_str.sub("$ ", ""))
# possible code to remove comma also?
end
You can get there two ways easily.
String's delete method is good for removing all occurrences of the target strings:
'$ 1.23'.delete('$ ,') # => "1.23"
'$ 123,456.00'.delete('$ ,') # => "123456.00"
Or, use String's tr method:
'$ 1.23'.tr('$, ', '') # => "1.23"
'$ 123,456.00'.tr('$ ,', '') # => "123456.00"
tr takes a string of characters to search for, and a string of characters used to replace them. Consider it a chain of gsub methods, one for each character.
BUT WAIT! THERE'S MORE! If the replacement string is empty, all characters in the search string will be removed.

What is wrong with this Regex in Ruby on Rails?

I've written a regex to help validate a String for game character names. It's somehow passing seemingly invalid strings and not passing seemingly valid strings.
Requirements:
Starts with a capital letter
Has any number of alphanumeric characters after that (this includes spaces)
This is the rails code that does the validation in the Character Model:
validates :name, format: { with: %r{[A-Z][a-zA-Z0-9\s]*} }
Here's the unit test I'm using
test "character name should be properly formatted and does not contain any special characters" do
character = get_valid_character
assert character.valid?
character.name = "aBcd"
assert character.invalid?, "#{character.name} should be invalid"
character.name = "Number 1"
assert character.valid?, "#{character.name} should be valid"
character.name = "McDonalds"
assert character.valid?, "#{character.name} should be valid"
character.name = "Abcd."
assert character.invalid?, "#{character.name} should be invalid"
character.name = "Abcd%"
assert character.invalid?, "#{character.name} should be invalid"
end
The problems:
The regex passes "aBcd", "Abcd.", and "Abcd%" when it shouldn't. Now, I know this works because I tested this out in Python and it works just as you would expect.
What gives?
Thank you for your help!
Regular expressions look for matches anywhere in the given string unless told otherwise.
So the test string 'aBcd' is invalid, but it contains a valid substring: 'Bcd'. Same with 'Abcd%', where the valid substring is 'Abcd'.
If you want to match the entire string, use this as your regex:
# \A matches string beginning, \z matches string end
%r{\A[A-Z][a-zA-Z0-9\s]*\z}
PS: Some people will say to match the beginning of a string with ^ and the end with $. In Ruby, those symbols match the beginning and end of a line, not a string. So "ABCD\n%" would still match if you used ^ and $, but won't match if you use \A and \z. See the Rails security guide for more on this.
If you only want to match the capital letter at the beginning of the string, you need to put in the "start of line" marker ^ so it would look like:
validates :name, format: { with: %r{^[A-Z][a-zA-Z0-9\s]*} }
Check out Rubular to play around with your regex

Rails validating full_name

Hey... how would you validate a full_name field (name surname).
Consider names like:
Ms. Jan Levinson-Gould
Dr. Martin Luther King, Jr.
Brett d'Arras-d'Haudracey
Brüno
Instead of validating the characters that are there, you might just want to ensure some set of characters is not present.
For example:
class User < ActiveRecord::Base
validates_format_of :full_name, :with => /\A[^0-9`!##\$%\^&*+_=]+\z/
# add any other characters you'd like to disallow inside the [ brackets ]
# metacharacters [, \, ^, $, ., |, ?, *, +, (, and ) need to be escaped with a \
end
Tests
Ms. Jan Levinson-Gould # pass
Dr. Martin Luther King, Jr. # pass
Brett d'Arras-d'Haudracey # pass
Brüno # pass
John Doe # pass
Mary-Jo Jane Sally Smith # pass
Fatty Mc.Error$ # fail
FA!L # fail
#arold Newm#n # fail
N4m3 w1th Numb3r5 # fail
Regular expression explanation
NODE EXPLANATION
--------------------------------------------------------------------------------
\A the beginning of the string
--------------------------------------------------------------------------------
[^`!##\$%\^&*+_=\d]+ any character except: '`', '!', '#', '#',
'\$', '%', '\^', '&', '*', '+', '_', '=',
digits (0-9) (1 or more times (matching
the most amount possible))
--------------------------------------------------------------------------------
\z the end of the string
Any validation you perform here is likely to break down unless it is extremely general. For instance, enforcing a minimum length of 3 is probably about as reasonable as you can get without getting into the specifics of what is entered.
When you have names like "O'Malley" with an apostrophe, "Smith-Johnson" with a dash, "Andrés" with accented characters or extremely short names such as "Vo Ly" with virtually no characters at all, how do you validate without excluding legitimate cases? It's not easy.
At least one space and at least 4 char (including the space)
\A(?=.* )[^0-9`!##\\\$%\^&*\;+_=]{4,}\z

Resources