php regular expression for 4 characters - php

I am trying to construct a regular expression for a string which can have 0 upto 4 characters. The characters can only be 0 to 9 or a to z or A to Z.
I have the following expression, it works but I dont know how to set it so that only maximum of 4 characters are accepted. In this expression, 0 to infinity characters that match the pattern are accepted.
'([0-9a-zA-Z\s]*)'

You can use {0,4} instead of the * which will allow zero to four instances of the preceding token:
'([0-9a-zA-Z\s]{0,4})'
(* is actually the same as {0,}, i.e. at least zero and unbounded.)

If you want to match a string that consists entirely of zero to four of those characters, you need to anchor the regex at both ends:
'(^[0-9a-zA-Z]{0,4}$)'
I took the liberty of removing the \s because it doesn't fit your problem description. Also, I don't know if you're aware of this, but those parentheses do not form a group, capturing or otherwise. They're not even part of the regex; PHP is using them as regex delimiters. Your regex is equivalent to:
'/^[0-9a-zA-Z]{0,4}$/'
If you really want to capture the whole match in group #1, you should add parentheses inside the delimiters:
'/(^[0-9a-zA-Z]{0,4}$)/'
... but I don't see why you would want to; the whole match is always captured in group #0 automatically.

You can use { } to specify finite quantifiers:
[0-9a-zA-Z\s]{0,4}
http://www.regular-expressions.info/reference.html

You can avoid regular expressions completely.
if (strlen($str) <= 4 && ctype_alnum($str)) {
// contains 0-4 characters, that are either letters or digits
}
ctype_alnum()

Related

Regex validation pattern only allows one character [duplicate]

This question already has answers here:
How to regex match entire string instead of a single character
(2 answers)
Closed 3 years ago.
I'm trying to make functions for validating usernames, emails, and passwords and my regex isn't working. My regex for usernames is ^[a-zA-Z0-9 _-]$ and when I put anything through that should work it always returns false.
As I understand it, the ^ and $ at the beginning and the end means that it makes sure the entire string matches this regular expression, the a-z and A-Z allows all letters, 0-9 allows all numbers, and the last three characters (the space, underscore, and dash) allow the respective characters.
Why is my regular expression not evaluating properly?
You need a quantifier, + or *. As it was written that only allows 1 of the characters in the character class.
Your a-zA-Z0-9_ also can be replaced with \w. Try:
^[\w -]+$
+ requires 1 or more matches. * requires 0 or more matches so if an empty string is valid use *.
Additionally you could use \h in place of the space character if tabs are allowed. That is the metacharacter for a horizontal space. I find it easier to read than the literal space.
Per comment, Update:
Since it looks like you want the string to be between a certain number of characters we can get more specific with the regex. A range can be created with {x,y} which will replace the quantifier.
^[\w -]{3,30}$
Additionally in PHP you must provide delimiters at the start and end of the regex.
preg_match("/^[\w -]{3,30}$/", $username);
Additionally, you should enable error reporting so you get these useful errors in the future. See https://stackoverflow.com/a/21429652/3783243
You're not specifying the character count. Lets try this instead:
^[A-z0-9]*$
Where [A-z0-9] states that you can use any alphanumeric characters and that it is case sensitive.
The * specifies how many characters, and in this case is unlimited. If you wanted to max out your username length to 10 characters, then you could change it to:
^[A-z0-9]{10}$
Whereby the {10} is specifying a maximum of 10 characters.
UPDATE
To also allow the use of underscores, hyphens and blank spaces (anywhere in the string) - use the below:
^[A-z0-9 _-]{10}$

Using Multiple Regular Expressions in PHP

I need to write a regular expression that will evaluate the following conditions:
2 consecutive lower case characters
at least 1 digit
at least 1 upper case character
2 consecutive identical punctuation characters
For example, the string 'aa1A!!' should match, as should '!!A1aa'.
I have written the following regular expression:
'/(?=([a-z]){2,})(?=[0-9])(?=[A-Z])(?=(\W)\1)/'
I have found each individual expression works, but I am struggling to put it all together. What am I missing?
First, your pattern must be anchored to be sure that lookaheads are only tested from the position at the start of string. Then, since your characters can be everywhere in the string, you need to start the subpatterns inside lookahead with .*.
\W is a character class for non-word characters (all that is not [A-Za-z0-9_] that includes spaces, control characters, accented letters...). IMO, \pP or [[:punct:]] are more appropriate.
/^(?=.*[a-z]{2})(?=.*[0-9])(?=.*[A-Z])(?=.*(\pP)\1)/
About the idea to make 4 patterns instead of 1, it looks like a good idea, it tastes like a good idea, but it's useless and slower. However, it can be interesting if you want to know what particular rule fails.

Regular Expression of a particular String in PHP

I have this few strings:
'user/1/myid_print'
'user/2/myid_print'
'user/3/myid_print'
'user/4/myid_print'
'user/5/myid_print'
The second part is the dynamic one which must contain only integers. What is it's regular expression?
Try this:
/user\/\d+\/myid_print/
the \d+ matches a number which contains at least one digit.
if it is a non-zero number, replace the \d+ with [1-9]\d*
It depends a bit on what language you're using, but one valid answer for Python is:
user/\d/myid_print
The / character is often used in describing regular expressions and sometimes needs \ before it to make it match part of the string, a valid answer might be:
user\/\d\/myid_print
These match the text "user/" and "/myid_print" literally, and \d matches the pattern "any digit 0-9". If you need to match the numbers 1,2,3,4,5 only, then use [1-5] instead of \d
Test it here: https://regex101.com/r/mS4xN4/1

Why preg_match("/[^(22|75)]/", "25") returns false?

I want to test that a given string does not belong to the following group of strings: 22 75.
Could anyone please tell why PHP's preg_match("/[^(22|75)]/", "25") returns 0?
The weirdest thing is that preg_match("/[^(22|76)]/", "25") returns 1 as expected...
Edit:
I guess I understand the reason and the nature of my mistake, not how to make a check that a given two-digit number does not match 20,21,22,23,24, 75,76,77,78,79,80 ?
I need to assemble an expression to check a given age against the list of allowed ages (this presumes only two-digit numbers)
I can not use anything other than preg_match() (!preg_match() is not available in my case), I can only play with RegEx pattern.
Time for a Regular Expressions Lesson!
Explanation of your regular expressions
[^(22|75)]
Matches false because it is looking for the following:
A single character NOT in this list of characters: |()275
[^(22|76)]
Matches true because it is looking for:
A single character NOT in this list of characters: |()276
Why does it do this?
You wrapped your regex in a character class (click for more info)
To give an example of how character classes work, look at this regex:
[2222222222222221111111199999999999]
This character class will only match ONE character, if it is a 2,1 or a 9.
How to make it work for you:
To match the number 25 (or 22, 52, and 55), you can use this character class:
[25]{2}
This will match a 2 digit number containing either 2 or 5 at either place.
What are character classes
A character class is a collection of characters (not strings). With a character class, you're telling the regex engine to match only one out of several characters.
For example, if you wanted to match an a or e, you'd write [ae]. If you wanted to match grey or gray, you'd write gr[ae]y.
Explanation for first regex
[^(22|75)]
As said above, character classes match a single character from the list. Here, you're using ^ to get a negated character class, so this will match a single character that's not in the supplied list. In this case, our list contains the following characters:
( 2 2 | 7 5 )
Multiple characters are only counted once. So this effectively becomes:
( 2 | 7 5 )
25 is the string you're matching against. The regular expression asks: Does the supplied string contains a single character that's not in the above list? 2 and 5 are in the list, so the answer is No. That explains why preg_match() returns false (not false, 0 to be precise).
Explanation for second regex
/[^(22|76)]/
It is same as above. The only difference here is that 5 changed to 6. It now checks for the absense of any of the following characters:
( 2 | 7 6 )
The supplied string is still the same as before - 25. Does the string contain any character that's not in the list above? Yes! It does contain 5 (which is not in the list anymore). That explains why preg_match() returns 1.
Difference between character classes and alternation
They look similar but they do different things. Alternation can be used when you want to match a single regular expression out of several possible regular expressions. Unlike character classes, alternation works with a regex. A simple string, say foo is also a valid regular expression. It matches f followed by o, followed by o.
Use character class when you want to match one of the included characters. Use alternation when you want to match between n number of strings.
How should you modify the regex to obtain correct results
Negate your preg_match() call and use the regex (22|75):
if (!preg_match('/(22|75)/', '25')) {
# code...
}
This is the easiest approach. If you want to achieve this directly using a regex, then you may want to use look-arounds.
Alternative solution
If this is exactly what you're trying to do, then you don't need a regular expression at all. Leverage PHP's built-in functions for string manipulation! Not only it will be faster, it will be more readable too.
In this case, a simple in_array() should suffice:
if(!in_array('25', array(25,75))) {
# code ...
}
In regular expression, [...] match any character inside the bracket.
To be more correct:
[^...]: match any charcter not listed inside the bracket. (^: negate)
Remove the [, and ] if you want to match string that starts with 22 or 76.
Your regex is asking "does the string contain a character that is not (, 2, 7, 5, | or )?"
This is obviously not what you want.
Try this:
if( !in_array("25", array("22","75")))
^ inside of [...] is a negation of a character list.
(22|76)
Regex multiple character negation is a very tricky subject and can't be easily resolved.
But you could invert the return result of preg_match function ie.:
if(!preg_match('#22|76#', '25', $matches))
doSomething();

PHP regex digit length only 5 or 9

I need a regular expression for string validation. String can be empty, can have 5 digits, and can have 9 digits. Other situations is invalid. I am using the next regex:
/\d{5}|\d{9}/
But it doesn't work.
Just as Marc B said in the comments, I would use this regular expression:
/^(\d{5}(\d{4})?)?$/
This matches either exactly five digits that might be followed by another four digits (thus nine digits in total) or no characters at all (note the ? quantifier around the digits expression that makes the group optional).
The advantage of this pattern in opposite to the other mentioned patterns with alternations is that this won’t require backtracking if matching five digits failed.
use anchors and "?" to allow empty string
/^(\d{5}|\d{9})?$/
~^(?:\d{5}|\d{9}|)$~
You forgot the anchors ^ and $. Without them the string would match those digits anywhere in the string, not only at beginning or end. Furthermore you didn't cover the empty string case.
"doesn't work" isn't much help. but wouldn't it be something like this?
/^(\d{5}|\d{9}|)$/
(Bit rusty on regexp, but i'm trying to do is "start, then 5 digits OR 9 digits OR nothing, then end)
The answer as to why it doesent work is with Perl style regex's alternations are prioritized from left to right.
Change it to:
/\d{9}|\d{5}/ (Though, this won't tell you anything else about 6-8 and 10-infinity
unless its anchored with assertions or something else.)
/^(\d{5}|\d{9}|)$/

Categories