20

I am trying to validate strings in ruby. Any string which contains spaces,under scores or any special char should fail validation. The valid string should contain only chars a-zA-Z0-9 My code looks like.

def validate(string)
    regex ="/[^a-zA-Z0-9]$/
    if(string =~ regex)
        return "true"
    else
        return "false"
end

I am getting error: TypeError: type mismatch: String given.

Can anyone please let me know what is the correct way of doing this?

6
  • See ideone.com/TKD3QW Commented Oct 21, 2015 at 19:03
  • 3
    @sln: ^ and $ don't mean what you think they do in Ruby regexes, you almost always want \A and \z instead. Commented Oct 21, 2015 at 19:21
  • 1
    @muistooshort - Ahh, ruby the oddball. Yes, then \A and \z it is then. Commented Oct 21, 2015 at 19:27
  • 1
    You can just use \w for any [a-zA-Z0-9], as a shortcut, btw. Commented Oct 21, 2015 at 20:00
  • 4
    @frosty: \w also matches _ (underscore/low line). Commented Oct 21, 2015 at 20:28

8 Answers 8

14

If you are validating a line:

def validate(string)
  !string.match(/\A[a-zA-Z0-9]*\z/).nil?
end

No need for return on each.

Sign up to request clarification or add additional context in comments.

Comments

6
def alpha_numeric?(char)  
 
   if (char =~ /[[:alpha:]]/ || char =~ /[[:digit:]]/)
      true
   else
      false
   end

end

OR

def alpha_numeric?(char)  
 
   if (char =~ /[[:alnum:]]/)
      true
   else
      false
   end

end

We are using regular expressions that match letters & digits:

The above [[:alpha:]] ,[[:digit:]] and [[:alnum:]] are POSIX bracket expressions, and they have the advantage of matching Unicode characters in their category. Hope this helps.

checkout the link below for more options: Ruby: How to find out if a character is a letter or a digit?

Comments

5

You can just check if a special character is present in the string.

def validate str
 chars = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
 str.chars.detect {|ch| !chars.include?(ch)}.nil?
end

Result:

irb(main):005:0> validate "hello"
=> true
irb(main):006:0> validate "_90 "
=> false

1 Comment

I suggest str.chars.all? {|ch| chars.include?(ch)} (for better readability). Also, using chars as a variable name along with the method chars could be confusing. Best to avoid variable names that are the names of methods.
2

Use .match? in Ruby 2.4+.

Ruby 2.4 introduced a convenient boolean-returning .match? method.

In your case, I would do something like this:

# Checks for any characters other than letters and numbers.
# Returns true if there are none. Returns false if there are one or more.
#
def valid?( string )
  !string.match?( /[^a-zA-Z0-9]/ ) # NOTE: ^ inside [] set turns it into a negated set.
end

Comments

1

No regex:

def validate(str)
  str.count("^a-zA-Z0-9").zero?  # ^ means "not"
end

4 Comments

It's curious that all but one of the answers has received a downvote. I received mine today.
kind of odd to say no regex since you're passing in a regex
@drewish Sure, it's similar. A valid regex would be /[^a-zA-Z0-9]/ (as in the answer by Joshua Pinter.
No, I was mistaken. I thought the count method was just converting the string version of a regex you passed in to a a regex. Looking at the docs I'm understanding your point that they use the same character class syntax, but that it's not a full regex.
1

Great answers above but just FYI, your error message is because you started your regex with a double quote ". You'll notice you have an odd number (5) of double quotes in your method.

Additionally, it's likely you want to return true and false as values rather than as quoted strings.

Comments

1

Similar to the very efficient regex-ish approach mentioned already by @steenslag and nearly just as fast:

str.tr("a-zA-Z0-9", "").length.zero?

OR

str.tr("a-zA-Z0-9", "") == 0

One benefit of using tr though is that you could also optionally analyze the results using the same basic formula:

str = "ABCxyz*123$"

rejected_chars = str.tr("a-zA-Z0-9", "")
#=>  *$

is_valid = rejected_chars.length.zero?
#=> false

Comments

0

Similar to @rohit89:

VALID_CHARS = [*?a..?z, *?A..?Z, *'0'..'9']
  #=> ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
  #    "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
  #    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
  #    "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
  #    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

def all_valid_chars?(str)
  a = str.chars
  a == a & VALID_CHARS
end

all_valid_chars?('a9Z3')  #=> true
all_valid_chars?('a9 Z3') #=> false

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.