A solid nickname regexp - php

I want a regular expression to validate a nickname: 6 to 36 characters, it should contain at least one letter. Other allowed characters: 0-9 and underscores.
This is what I have now:
if(!preg_match('/^.*(?=\d{0,})(?=[a-zA-Z]{1,})(?=[a-zA-Z0-9_]{6,36}).*$/i', $value)){
echo 'bad';
}
else{
echo 'good';
}
This seems to work, but when a validate this strings for example:
11111111111a > is not valid, but it should
aaaaaaa!aaaa > is valid, but it shouldn't
Any ideas to make this regexp better?

I would actually split your task into two regex:
to find out whether it's a valid word: /^\w{6,36}$/i
to find out whether it contains a letter /[a-z]/i
I think it's much simpler this way.

Try this:
'/^(?=.*[a-z])\w{6,36}$/i'
Here are some of the problems with your original regex:
/^.*(?=\d{0,})(?=[a-zA-Z]{1,})(?=[a-zA-Z0-9_]{6,36}).*$/i
(?=\d{0,}): What is this for??? This is always true and doesn't do anything!
(?=[a-zA-Z]{1,}): You don't need the {1,} part, you just need to find one letter, and i flag also allows you to omit A-Z
/^.*: You're matching these outside of the lookaround; it should be inside
(?=[a-zA-Z0-9_]{6,36}).*$: this means that as long as there are between 6-36 \w characters, everything else in the rest of the string matches! The string can be 100 characters long mostly containing illegal characters and it will still match!

You can do it easily using two calls to preg_match as:
if( preg_match('/^[a-z0-9_]{6,36}$/i',$input) && preg_match('/[a-z]/i',$input)) {
// good
} else {
// bad
}

Related

PHP preg_match regular expression for find date in string

I try to make system that can detect date in some string, here is the code :
$string = "02/04/16 10:08:42";
$pattern = "/\<(0?[1-9]|[12][0-9]|3[01])\/\.- \/\.- \d{2}\>/";
$found = preg_match($pattern, $string);
if ($found) {
echo ('The pattern matches the string');
} else {
echo ('No match');
}
The result i found is "No Match", i don't think that i used correct regex for the pattern. Can somebody tell me what i must to do to fix this code
First of all, remove all gibberish from the pattern. This is the part you'll need to work on:
(/0?[1-9]|[12][0-9]|3[01]/)
(As you said, you need the date only, not the datetime).
The main problem with the pattern, that you are using the logical OR operators (|) at the delimiters. If the delimiters are slashes, then you need to replace the tube characters with escaped slashes (/). Note that you need to escape them, because the parser will not take them as control characters. Like this: \/.
Now, you need to solve some logical tasks here, to match the numbers correctly and you're good to go.
(I'm not gonna solve the homework for you :) )
These articles will help you to solve the problem tough:
Character classes
Repetition opetors
Special characters
Pipe character (alternation operator)
Good luck!
In your comment you say you are looking for yyyy, but the example says yy.
I made a code for yy because that is what you gave us, you can easily change the 2 to a 4 and it's for yyyy.
preg_match("/((0|1|2|3)[0-9])\/\d{2}\/\d{2}/", $string, $output_array);
Echo $output_array[1]; // date
Edit:
If you use this pattern it will match the time too, thus make it harder to match wrong.
((0|1|2|3)[0-9])/\d{2}/\d{2}\s+\d{2}:\d{2}:\d{2}
http://www.phpliveregex.com/p/fjP
Edit2:
Also, you can skip one line of code.
You first preg_match to $found and then do an if $found.
This works too:
If(preg_match($pattern, $string, $found))}{
Echo $found[1];
}Else{
Echo "nothing found";
}
With pattern and string as refered to above.
As you can see the found variable is in the preg_match as the output, thus if there is a match the if will be true.

Regex for Chinese / Japanese letters

Okai so I already have this regular expression for names allowed on my website.
However, I also wish to add other possible letters that names use.
Does someone have a good regex or know how I can make this more complete? I have searched for quite a while now, and I can't find anything that suits my needs.
This is my current regex for checking names:
$regex = "/^([a-zA-ZàáâäãåąčćęèéêëėįìíîïłńòóôöõøùúûüųūÿýżźñçčšžÀÁÂÄÃÅĄĆČĖĘÈÉÊËÌÍÎÏĮŁŃÒÓÔÖÕØÙÚÛÜŲŪŸÝŻŹÑßÇŒÆČŠŽ∂ð ,.'-])+$/";
if(preg_match($regex, $fullname)){
// do something
}
As Lucas Trzesniewski has mentioned, the \p{L} will include the [a-zA-Z], so I have removed from the pattern.
Thus, combining the character lists that you have included in the example; the pattern will look like this, /^[\p{L}\s,.'-]+$/u
^[]+$ matches the string from start to end, thus + also imply the need of matching one or more
\p{L} matches unicode characters
\s,.'- matches space, comma, period, single quotation, and dash
u the PCRE_UTF8 modifier, this modifier turns on additional functionality of PCRE that is incompatible with Perl.
if(preg_match("/^[\p{L}\s,.'-]+$/u", "お元気ですか你好吗how are you你好嗎,.'-") === 1) {
echo "match";
}
else {
echo "no match";
}
// match
if(preg_match("/^[\p{L}\s,.'-]+$/u", "お元気ですか你好吗how are you你好_嗎-,.'") === 1) {
echo "match";
}
else {
echo "no match";
}
// no match as there are underscore in 你好_嗎

PHP, Regex - how to disallow non-alphanumeric characters

I'm trying to make a regex that would allow input including at least one digit and at least one letter (no matter if upper or lower case) AND NOTHING ELSE. Here's what I've come up with:
<?php
if (preg_match('/(?=.*[a-z]+)(?=.*[0-9]+)([^\W])/i',$code)) {
echo "=)";
} else {
echo "=(";
}
?>
While it gives false if I use only digits or only letters, it gives true if I add $ or # or any other non-alphanumeric sign. Now, I tried putting ^\W into class brackets with both a-z and 0-9, tried to use something like ?=.*[^\W] or ?>! but I just can't get it work. Typing in non-alphanums still results in true. Halp meeee
You need to use anchors so that it matches against the entire string.
^(?=.*[a-z]+)(?=.*[0-9]+)(\w+)$
Since you are using php, why even use regex at all. You can use ctype_alnum()
http://php.net/manual/en/function.ctype-alnum.php

Check if variable contains text or numbers

Im creating a search function. The users are only allowed to use a-z A-Z and 0-9. How do i check if $var only contains text or numbers, and not special characters ?
I have tried something like this:
if (!preg_match('/[^a-z]/i', $search) {
$error = "error...";
}
If anyone have a smarter solution, please let me know. It could also be something checking for special characters.
You're pretty much there. Just add numbers 0-9 to your regular expression, like this:
if(preg_match('/[^a-z0-9]/i', $search))
{
$error = "Error...";
}
The /i flag tells the expression to ignore case, so A-Z is not needed inside the letter list.
In your original code, you were looking for anything that wasn't a letter or number, while also checking to see if preg_match() hadn't matched anything - you created a double negative. The code above executes the if() if anything that isn't a letter or number is found. Full credit to #brain in the comments.
To allow other characters, simply add them to the characters inside the braces:
if(preg_match('/[^a-z0-9 \.]/i', $search))
{
$error = "Error...";
}
This example allows spaces and . (dots).
Something like this:
if(!preg_match('/^[a-zA-Z0-9]+$/', $search)) {
// error
}

How to check if a string is in an array?

I basically need a function to check whether a string's characters (each character) is in an array.
My code isn't working so far, but here it is anyway,
$allowedChars = array("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"," ","#",".","-","_","+"," ");
$input = "Test";
$input = str_split($input);
if (in_array($input,$allowedChars)) {echo "Yep, found.";}else {echo "Sigh, not found...";}
I want it to say 'Yep, found.' if one of the letters in $input is found in $allowedChars. Simple enough, right? Well, that doesn't work, and I haven't found a function that will search a string's individual characters for a value in an array.
By the way, I want it to be just those array's values, I'm not looking for fancy html_strip_entities or whatever it is, I want to use that exact array for the allowed characters.
You really should look into regex and the preg_match function: http://php.net/manual/en/function.preg-match.php
But, this should make your specific request work:
$allowedChars = array("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"," ","#",".","-","_","+"," ");
$input = "Test";
$input = str_split($input);
$message = "Sigh, not found...";
foreach($input as $letter) {
if (in_array($letter, $allowedChars)) {
$message = "Yep, found.";
break;
}
}
echo $message;
Are you familiar with regular expressions at all? It's sort of the more accepted way of doing what you're trying to do, unless I'm missing something here.
Take a look at preg_match(): http://php.net/manual/en/function.preg-match.php
To address your example, here's some sample code (UPDATED TO ADDRESS ISSUES IN COMMENTS):
$subject = "Hello, this is a string";
$pattern = '/[a-zA-Z0-9 #._+-]*/'; // include all the symbols you want to match here
if (preg_match($pattern, $subject))
echo "Yep, matches";
else
echo "Doesn't match :(";
A little explanation of the regex: the '^' matches the beginning of the string, the '[a-zA-Z0-9 #._+-]' part means "any character in this set", the '*' after it means "zero or more of the last thing", and finally the '$' at the end matches the end of the string.
A somewhat different approach:
$allowedChars = array("a","b","c","d","e");
$char_buff = explode('', "Test");
$foundTheseOnes = array_intersect($char_buff, $allowedChars);
if(!empty($foundTheseOnes)) {
echo 'Yep, something was found. Let\'s find out what: <br />';
print_r($foundTheseOnes);
}
Validating the characters in a string is most appropriately done with string functions.preg_match() is the most direct/elegant method for this task.
Code: (Demo)
$input="Test Test Test Test";
if(preg_match('/^[\w +.#_-]*$/',$input)){
echo "Input string does not contain any disallowed characters";
}else{
echo "Input contains one or more disallowed characters";
}
// output: Yes, input contains only allowed characters
Pattern Explanation:
/ # start pattern
^ # start matching from start of string
[\w +.#-] # match: a-z, A-Z, 0-9, underscore, space, plus, dot, atsign, hyphen
* # zero or more occurrences
$ # match until end of string
/ # end pattern
Significant points:
The ^ and $ anchors are crucial to ensure that the entire string is validated versus just a substring of the string.
The \w (a.k.a. "any word character" -> a shorthand character class) is the easy way to write: [a-zA-Z0-9_]
The . dot character loses its "match anything (almost)" meaning and becomes literal when it is written inside of a character class. No escaping slash is necessary.
The hyphen inside of a character class can be written without an escaping slash (\-) so long as the it is positioned at the start or end of the character class. If the hyphen is not at the start/end and it is not escaped, it will create a range of characters between the characters on either side of it.Like it or not, [.-z] will not match a hyphen symbol because it does not exist "between" the dot character and the lowercase letter z on the ascii table.
The * that follows the character class is the "quantifier". The asterisk means "0 or more" of the preceding character class. In this case, this means that preg_match() will allow an empty string. If you want to deny an empty string, you can use + which means "1 or more" of the preceding character class. Finally, you can be far more specific about string length by using a number or numbers in a curly bracketed expression.
{8} would mean the string must be exactly 8 characters long.
{4,} would mean the string must be at least 4 characters long.
{,10} would mean the string length must be between 0 and 10.
{5,9} would mean the string length must be between 5 and 9 characters.
All of that advice aside, if you absolutely must use your array of characters AND you wanted to use a loop to check individual characters against your validation array (and I certainly don't recommend it), then the goal should be to reduce the number of array elements involved so as to reduce total iterations.
Your $allowedChars array has multiple elements that contain the space character, but only one is necessary. You should prepare the array using array_unique() or a similar technique.
str_split($input) will run the chance of generating an array with duplicate elements. For example, if $input="Test Test Test Test"; then the resultant array from str_split() will have 19 elements, 14 of which will require redundant validation checks.
You could probably eliminate redundancies from str_split() by calling count_chars($input,3) and feeding that to str_split() or alternatively you could call str_split() then array_unique() before performing the iterative process.
Because you're just validating a string, see preg_match() and other PCRE functions for handling this instead.
Alternatively, you can use strcspn() to do...
$check = "abcde.... '; // fill in the rest of the characters
$test = "Test";
echo ((strcspn($test, $check) === strlen($test)) ? "Sigh, not found..." : 'Yep, found.');

Categories