dabadaba
dabadaba

Reputation: 9542

PHP preg_match: any letter but no numbers (and symbols)

I am trying to set a validation rule for a field in my form that checks that the input only contains letters.

At first I tried to make a function that returned true if there were no numbers in the string, for that I used preg_match:

function my_format($str)
{
   return preg_match('/^([^0-9])$', $str);
}

It doesn't matter how many times I look at the php manual, it seems like I won't get to understand how to create the pattern I want. What's wrong with what I made?

But I'd like to extend the question: I want the input text to contain any letter but no numbers nor symbols, like question marks, exclamation marks, and all those you can imagine. BUT the letters I want are not only a-z, I want letters with all kinds of accents, as those used in Spanish, Portuguese, Swedish, Polish, Serbian, Islandic...

I guess this is no easy task and hard or impossible to do with preg_match. It there any library that covers my exact needs?

Upvotes: 2

Views: 12355

Answers (4)

sjagr
sjagr

Reputation: 16512

Use the [:alpha:] POSIX expression.

function my_format($str) {
    return preg_match('/[[:alpha:]]+/u', $str);
}

The extra [] turns the POSIX into a range modified by the + to match 1 or more alphabetical characters. As you can see, the :alpha: POSIX matches accented characters as well

If you want to include whitespace, just add \s to the range:

preg_match('/[[:alpha:]\s]+/u', $str);

EDIT: Sorry, I misread your question when I looked over it a second time and thought you wanted punctuation. I've taken it back out.

Upvotes: 1

David Lin
David Lin

Reputation: 13353

First of all,Merry Christmas.

You are on the right track with the first one, just missing a + to match one or more non-number characters:

preg_match('/^([^0-9]+)$/', $str);

As you can see, 0-9 is a range, from number 0 to 9. This applies to some other cases, like a-z or A-Z, the '-' is special and it indicates that it is a range. for 0-9, you can use shorthand of \d like:

preg_match('/^([^\d]+)$/', $str);

For symbols, if your list is punctuations . , " ' ? ! ; : # $ % & ( ) * + - / < > = @ [ ] \ ^ _ { } | ~, there is a shorthand.

preg_match('/^([^[:punct:]]+)$/', $str);

Combined you get:

preg_match('/^([^[:punct:]\d]+)$/', $str);

Upvotes: 3

revo
revo

Reputation: 48751

function my_format($str)
{
   return preg_match('/^\p{L}+$/', $str);
}

Simpler than you think about!

\p{L} matches any kind of letter from any language

Upvotes: 2

Jonny 5
Jonny 5

Reputation: 12389

If you're using utf-8 encoded input, go for unicode regex. Using the u modifier.

This one would match a string that only consists of letters and any kind of whitespace/invisible separators:

preg_match('~^[\p{L}\p{Z}]+$~u', $str);

Upvotes: 6

Related Questions