I want to use preg_match() such that there should not be special characters such as ``##$%^&/ '` in a given string.
For example :
Coding : Outputs valid
: Outputs Invalid(String beginning with space)
Project management :Outputs valid (space between two words are valid)
'Design23' :Outputs valid
23Designing : outputs invalid
123 :Outputs invalid
I tried but could not reach to a valid answer.
Does a regex like this help?
^[a-zA-Z0-9]\w*$
It means:
^ = this pattern must start from the beginning of the string
[a-zA-Z0-9] = this char can be any letter (a-z and A-Z) or digit (0-9, also see \d)
\w = A word character. This includes letters, numbers and white-space (not new-lines by default)
* = Repeat thing 0 or more times
$ = this pattern must finish at the end of the string
To satisfy the condition I missed, try this
^[a-zA-Z0-9]*\w*[a-zA-Z]+\w*$
The extra stuff I added lets it have a digit for the first character, but it must always contain a letter because of the [a-zA-Z]+ since + means 1 or more.
Try
'/^[a-zA-Z][\w ]+$/'
If this is homework, you maybe should just learn regular expressions:
Regular expressions tutorial
Regular expressions reference
PCRE syntax reference for PHP
Related
I understand that the regex pattern must match a string which starts with the combination and the repetition of the following characters:
a-z
A-Z
a white-space character
And there is no limitation to how the string may end!
First Case
So a string such as uoiui897868 (any string that only starts with space, a-z or A-Z) matches the pattern... (Sure it does)
Second Case
But the problem is a string like 76868678jugghjiuh (any string that only starts with a character other than space, a-z or A-Z) matches too! This should not happen!
I have checked using the php function preg_match() too , which returns true (i.e. the pattern matches the string).
Also have used other online tools like regex101 or regexr.com. The string does match the pattern.
Can anybody could help me understand why the pattern matches the string described in the second case?
/^[a-zA-Z ]*/
Your regex will match strings that "begin with" any number (including zero) of letters or spaces.
^ means "start of string" and * means "zero or more".
Both uoiui897868 and 76868678jugghjiuh start with 0 or more letters/spaces, so they both match.
You probably want:
/^[a-zA-Z ]+/
The + means "one or more", so it won't match zero characters.
Your regex is completely useless: it will trivially match any string (empty, non-empty, with numbers, without,...), regardless of its structure.
This because
with ^, you enforce the begin of the string, now every string has a start.
You use a group [A-Za-z ], but you use a * operator, so 0 or more repititions. Thus even if the string does not contain (or begins with) a character from [A-Za-z ], the matcher will simply say: zero matches and parse the remaining of the string.
You need to use + instead of * to enforce "at least one character".
The '*' quantifier on the end means zero or more matches of the character, so all strings will match. Perhaps you want to drop the wildcard quantifier, or change it to a '+' quantifier, and add a '$' on the end to test the whole string.
What you really want is to match one or more of the preceding characters.
For that you use +
/^[a-zA-Z ]+/
I would like to use php's preg_match to capture substrings which comprise:
A-Z, a-z, all accented chars
space
hyphen
It must not capture strings with anything else in them, including numeric chars.
This example is close but also catches strings containing numeric chars:
preg_match("/([\p{L} -]+)/u", $string)
A similar question already had an answer (the one above) but it doesn't work...
If I understand your problem correctly (which I might not have), then you simply want to use the ^ and $ characters to specify that "the match HAS to start here and the match HAS to end here":
/^([\p{L} -]+)$/u
^ ^
Then preg_match would only return true if the string had nothing else in it.
DEMO
Edit:
If hyphens/spaces are only allowed in the middle:
/^([\p{L}](?:[\p{L} -]+[\p{L}])?)$/u
DEMO
in my program php, I want the user doesn't enter any caracters except the alphabets
like that : "dgdh", "sgfdgdfg" but he doesn't enter the numbers or anything else like "7657" or "gfd(-" or "fd54"
I tested this function but it doesn't cover all cases :
preg_match("#[^0-9]#",$_POST['chaine'])
how can I achieve that, thank you in advance
The simplest can be
preg_match('/^[a-z]+$/i', $_POST['chaine'])
the i modifier is for case-insensitive. The + is so that at least one alphabet is entered. You can change it to * if you want to allow empty string. The anchor ^ and $ enforce that the whole string is nothing but the alphabets. (they represent the beginning of the string and the end of the string, respectively).
If you want to allow whitespace, you can use:
Whitespace only at the beginning or end of string:
preg_match('/^\s*[a-z]+\s*$/i', $_POST['chaine'])
Any where:
preg_match('/^[a-z][\sa-z]*$/i', $_POST['chaine']) // at least one alphabet
Only the space character is allowed but not other whitespace:
preg_match('/^[a-z][ a-z]*$/i', $_POST['chaine'])
Two things. Firstly, you match non-digit characters. That is obviously not the same as letter characters. So you could simply use [a-zA-Z] or [a-z] and the case-insensitive modifier instead.
Secondly you only try to find one of those characters. You don't assert that the whole string is composed of these. So use this instead:
preg_match("#^[a-z]*$#i",$_POST['chaine'])
Only match letters (no whitespace):
preg_match("#^[a-zA-Z]+$#",$_POST['chaine'])
Explanation:
^ # matches the start of the line
[a-zA-Z] # matches any letter (upper or lowercase)
+ # means the previous pattern must match at least once
$ # matches the end of the line
With whitespace:
preg_match("#^[a-zA-Z ]+$#",$_POST['chaine'])
I want to accept a list of character as input from the user and reject the rest. I can accept a formatted string or find if a character/string is missing.
But how I can accept only a set of character while reject all other characters. I would like to use preg_match to do this.
e.g. Allowable characters are: a..z, A..Z, -, ’ ‘
User must able to enter those character in any order. But they must not allowed to use other than those characters.
Use a negated character class: [^A-Za-z-\w]
This will only match if the user enters something OTHER than what is in that character class.
if (preg_match('/[^A-Za-z-\w]/', $input)) { /* invalid charcter entered */ }
[a-zA-Z-\w]
[] brackets are used to group characters and behave like a single character. so you can also do stuff like [...]+ and so on
also a-z, A-Z, 0-9 define ranges so you don't have to write the whole alphabet
You can use the following regular expression: ^[a-zA-Z -]+$.
The ^ matches the beginning of the string, which prevents it from matching the middle of the string 123abc. The $ similarly matches the end of the string, preventing it from matching the middle of abc123.
The brackets match every character inside of them; a-z means every character between a and z. To match the - character itself, put it at the end. ([19-] matches a 1, a 9, or a -; [1-9] matches every character between 1 and 9, and does not match -).
The + tells it to match one or more of the thing before it. You can replace the + with a *, which means 0 or more, if you also want to match an empty string.
For more information, see here.
You would be looking at a negated ^ character class [] that stipulates your allowed characters, then test for matches.
$pattern = '/[^A-Za-z\- ]/';
if (preg_match($pattern, $string_of_input)){
//return a fail
}
//Matt beat me too it...
^([a-zA-Z0-9!##$%^&*|()_\-+=\[\]{}:;\"',<.>?\/~`]{4,})$
Would this regular expression work for these rules?
Must be atleast 4 characters
Characters can be a mix of alphabet (capitalized/non-capitalized), numeric, and the following characters: ! # # $ % ^ & * ( ) _ - + = | [ { } ] ; : ' " , < . > ? /
It's intended to be a password validator. The language is PHP.
Yes?
Honestly, what are you asking for? Why don't you test it?
If, however, you want suggestions on improving it, some questions:
What is this regex checking for?
Why do you have such a large set of allowed characters?
Why don't you use /\w/ instead of /0-9a-zA-Z_/?
Why do you have the whole thing in ()s? You don't need to capture the whole thing, since you already have the whole thing, and they aren't needed to group anything.
What I would do is check the length separately, and then check against a regex to see if it has any bad characters. Your list of good characters seems to be sufficiently large that it might just be easier to do it that way. But it may depend on what you're doing it for.
EDIT: Now that I know this is PHP-centric, /\w/ is safe because PHP uses the PCRE library, which is not exactly Perl, and in PCRE, \w will not match Unicode word characters. Thus, why not check for length and ensure there are no invalid characters:
if(strlen($string) >= 4 && preg_match('[\s~\\]', $string) == 0) {
# valid password
}
Alternatively, use the little-used POSIX character class [[:graph:]]. It should work pretty much the same in PHP as it does in Perl. [[:graph:]] matches any alphanumeric or punctuation character, which sounds like what you want, and [[:^graph:]] should match the opposite. To test if all characters match graph:
preg('^[[:graph:]]+$', $string) == 1
To test if any characters don't match graph:
preg('[[:^graph:]]', $string) == 0
You forgot the comma (,) and full stop (.) and added the tilde (~) and grave accent (`) that were not part of your specification. Additionally just a few characters inside a character set declaration have to be escaped:
^([a-zA-Z0-9!##$%^&*()|_\-+=[\]{}:;"',<.>?/~`]{4,})$
And that as a PHP string declaration for preg_match:
'/^([a-zA-Z0-9!##$%^&*()|_\\-+=[\\]{}:;"\',<.>?\\/~`]{4,})$/'
I noticed that you essentially have all of ASCII, except for backslash, space and the control characters at the start, so what about this one, instead?
^([!-\[\]-~]{4,})$
You are extra escaping and aren't using some predefined character classes (such as \w, or at least \d).
Besides of that and that you are anchoring at the beginning and at the end, meaning that the regex will only match if the string starts and ends matching, it looks correct:
^([a-zA-Z\d\-!$##$%^&*()|_+=\[\]{};,."'<>?/~`]{4,})$
If you really mean to use this as a password validator, it reeks of insecurity:
Why are you allowing 4 chars passwords?
Why are you forbidding some characters? PHP can't handle some? Why would you care? Let the user enter the characters he pleases, after all you'll just end up storing a hash + salt of it.
No. That regular expression would not work for the rules you state, for the simple reason that $ by default matches before the final character if it is a newline. You are allowing password strings like "1234\n".
The solution is simple. Either use \z instead of $, or apply the D modifier to the regex.