vplusplus
vplusplus

Reputation: 603

Regex for ONE-or-more letters/digits And ZERO-or-more spaces

I want to allow 0 or more white spaces in my string and one or more A-Z or a-z or 0-9 in my string.

Regex allowing a space character in Java

suggests [0-9A-Za-z ]+.

I doubt that, this regex matches patterns having zero or more white spaces.

What to do to allow 0 or more whitespaces anywhere in the string and one or more characters anywhere in the string.

Will this work? ([0-9A-Za-z]+)([ ]*)

Upvotes: 24

Views: 87381

Answers (7)

Basheer AL-MOMANI
Basheer AL-MOMANI

Reputation: 15327

The most simple answer

* means zero or more equivalent to {0,}

+ means one or more equivalent to {1,}

so look at this

[A-Z]+ means at least one Capital Letter, can be written as [A-Z]{1,}

[!@#$%&]. means you can have these Special Characters zero or more times can be written as [!@#$%&]{0,}

sorry but

the purpose of this answer to be as Simple as possible

Upvotes: 13

Pedro Lobito
Pedro Lobito

Reputation: 98881

try {
    if (subjectString.matches("(?i)^(?=.*\\s*)(?!.*_)(?=.*[\\w]+)[\\w ]+$")) {
        // String matched entirely
    } else {
        // Match attempt failed
    } 
} catch (PatternSyntaxException ex) {
    // Syntax error in the regular expression
}

Or Simply:

^(.*\p{Blank}?\p{Alnum}+.*\p{Blank}?)$

Example

Upvotes: 0

Justin
Justin

Reputation: 25287

You are asking that the string (s) satisfies this condition (note: let c∈s mean c∈{x|x is a character in s}. Also, [] represent regex character classes):

(∀c∈s (c∈[0-9A-Za-z ])) ∧ (∃c∈s ∋ c∈[0-9A-Za-z])

Consider the negation:

¬((∀c∈s c∈[0-9A-Za-z ]) ∧ (∃c∈s ∋ c∈[0-9A-Za-z]))
⇔
(∃c∈s ∋ c∉[0-9A-Za-z ]) ∨ (∀c∈s c∉[0-9A-Za-z])
⇔
(∃c∈s ∋ c∈[^0-9A-Za-z ]) ∨ (∀c∈s c∈[^0-9A-Za-z])

So now we want to construct a regex that either contains a non-alphanumeric and non-space character or consists only of non-alphanumeric characters.

The first is easy: [^0-9A-Za-z ].
The second is like unto it: ^[^0-9A-Za-z]*$

Combine them together to get: [^0-9A-Za-z ]|^[^0-9A-Za-z]*$

Now we need to negate this regex. Obviously, we could just do (?![^0-9A-Za-z ]|^[^0-9A-Za-z]*$). Or we could manually negate the regex:

[^0-9A-Za-z ] becomes ^[0-9A-Za-z ]*$
^[^0-9A-Za-z]*$ becomes [0-9A-Za-z]. (note: we could easily have arrived here from the beginning)

But now we need to combine them with AND, not OR:

Since [0-9A-Za-z] is a subset of [0-9A-Za-z ], we can simply do this:

^[0-9A-Za-z ]*[0-9A-Za-z][0-9A-Za-z ]*$

Note that we can simplify it down to:

^[0-9A-Za-z ]*[0-9A-Za-z][ ]*$

This just requires that the character that matches [0-9A-Za-z] is the last character that could do so. We could also do

^[ ]*[0-9A-Za-z][0-9A-Za-z ]*$

Which would require that the character that matches [0-9A-Za-z] is the first character that could do so.

So now we're done. We can either use one of those or (?![^0-9A-Za-z ]|^[^0-9A-Za-z]*$).

Note: String#match acts as if the regex is ^ + regex + $ (where + is concatenation). This can throw a few things off.

Upvotes: 0

aliteralmind
aliteralmind

Reputation: 20163

Before looking at the other answers, I came up with doing it in two regexes:

boolean ok = (myString.matches("^[A-Za-z0-9 ]+$")  &&  !myString.matches("^ *$"));

This matches one-or-more letters/digits and zero-or-more spaces, but not only spaces (or nothing).

It could be made efficient by pre-creating a single matcher object for each regex:

   import  java.util.regex.Matcher;
   import  java.util.regex.Pattern;
public class OnePlusLetterDigitZeroPlusSpace  {
   //"": Unused search string, to reuse the matcher object
   private static final Matcher mtchr1PlusLetterDigitSpc = Pattern.compile("^[a-zA-z0-9 ]+$").matcher("");
   private static final Matcher mtchr0PlusSpc = Pattern.compile("^ *$").matcher("");
   public static final void main(String[] ignored)  {
      test("");
      test(" ");
      test("a");
      test("hello ");
      test(" hello ");
      test("hello there");
   }
   private static final void test(String to_search)  {
      System.out.print("\"" + to_search + "\": ");
      if(mtchr1PlusLetterDigitSpc.reset(to_search).matches()  &&  !mtchr0PlusSpc.reset(to_search).matches())  {
         System.out.println("good");
      }  else  {
         System.out.println("BAD");
      }
   }
}

Output:

[C:\java_code\]java OnePlusLetterDigitZeroPlusSpace
"": BAD
" ": BAD
"a": good
"hello ": good
" hello ": good
"hello there": good

Interesting regex question of the day.

Upvotes: 2

Cruncher
Cruncher

Reputation: 7812

I believe you can do something like this:

([ ]*+[0-9A-Za-z]++[ ]*+)+

This is 0 or more spaces, followed by at least 1 alphanum char, followed by 0 or more spaces

^^ that whole thing at least once.

Using Pshemo's idea of possessive quantifiers to speed up the regex.

Upvotes: 21

donut
donut

Reputation: 790

You can try also this :

  ^[0-9A-Za-z ]*[0-9A-Za-z]+[ ]*$

Upvotes: 7

Toto
Toto

Reputation: 91385

Use lookahead:

^(?=.*\s*)(?=.*[a-zA-Z0-9]+)[a-zA-Z0-9 ]+$

Upvotes: 4

Related Questions