Regex function not giving expected result - php

I'm trying to validate the username according to the following rule:
No space at beginning or end, at least 2 characters, must not have the following characters: \ " ' % ; ( )
The expression that I've written in PHP is :
if (preg_match('#[<>"\'%;()&\\\\]|\\.\\./#', $this->username) || StringHelper::strlen($this->username) < 2
|| $filterInput->clean($this->username, 'TRIM') !== $this->username || StringHelper::strlen($this->username) > 150)
{
return false; //false will display an error message
}
But on trying the following usernames :
userName<test : accepted as userName.
userName<>test: accepted as userNametest
userName>test :not accepted
So it should be matching on the < and > characters and they should be in the error message
But other parts of the validation are breaking that I think. Please let me know what is wrong in the regex expression.

Try this expression
^ +|[ )"'%;()]$
reg

Or this one:
$test=array("test>string"," test<string","abc;def","a(bc)d");
foreach($test as $t)
echo "$t: ".preg_match("/^[^\\\"'%;()]+$/",trim($t))."\n";
result:
test>string: 1
test<string: 1
abc;def: 0
a(bc)d: 0
Instead of testing for spaces at the beginning and the end I would simply trim them away!

wouldn't it be better with a
function isValidUsername(string $name, string &$failReason=null): bool {
if($name!==ltrim($name)){
$failReason = "username cannot start with spaces";
return false;
}
if($name!==rtrim($name)){
$failReason = "username cannot end with spaces";
return false;
}
$len = strlen($name);
if($len < 2){
$failReason = "username must be minimum 2 characters long";
return false;
}
if($len !== ($illegalPos = strcspn($name , '\\"\'%;()'))){
$failReason = "illegal character on position {$illegalPos}";
return false;
}
$failReason = "";
return true;
}
then you could also explain exactly what is wrong with the username... btw are you really intending to allow NULL bytes in your username? eg "a\x00b" is a valid username? i'd add \x00 to illegal characters and also do a if(!mb_check_encoding($name,'UTF-8')){$failReason="username must be UTF-8";return false;}

check out this article, it will direct and enlighten you on how to use regex
https://support.kobotoolbox.org/restrict_responses.html

Related

preg_match always returns 0

In the code below I control if the id in the database is a number. My problem is: the regular expression where I test the id always gives the nummber 0 back never 1 - even when the id is a number.
Can you help me to solve this?
This is the code with the problem:
$muster = "|^[0-9]+$|";
if(preg_match($muster, $_POST["Anzahl"]) == 0 || preg_match($muster, $_POST["id"]) == 0 || $_POST["Anzahl"] < 1) {
die("<a href='javascript:history.back()'>Eingabe überprüfen</a>");
}
I would use PHPValidate filters
Its easier and more convenient:
<?php
$str = "100";
if (filter_var($str, FILTER_VALIDATE_INT)) {
echo("Variable is an integer");
} else {
echo("Variable is not an integer");
}
?>
If filter_var(($str, FILTER_VALIDATE_INT)) is successful it will return 100 as integer, otherwise false
Btw there are many usefull filter: http://php.net/manual/de/filter.filters.validate.php

PHP validation check for numeric and alphabetic sequence [duplicate]

This question already has an answer here:
Reference - What does this regex mean?
(1 answer)
Closed 5 years ago.
one of the rules in our password creation is, it shouldn't contain a sequence of number or alphabets.
ex.12345, pwd45678, pwd_abcdef, pwd_abc123
all of these are not allowed.
Any suggestion how to check for sequence?
By sequence meaning it shouldn't be order like for numbers 1-10 or letters in the alphabet. So the password shouldn't contain alphabet sequence or order and numbers in 1-10 order. So password containing ABC or DEF or HIJK is not allowed and passwords containing number orders like 1234 or 4567 are not allowed but passwords containing ABNOE or 19334 is ok.
TIA
A specific rule for no 2 adjacent digits or letters:
if (preg_match("#(\d{2,}|[[:alpha:]]{2,})#u", $input)) {
return false;
}
You can try it out here.
However, there are packages available specifically for password strength checking. They will have configurable rules or tests.
you can use the code below,I used the "asci code" to resolve the problem, it is already tested for your examples :
<?php
$passwords = [
'12345',
'pwd45678',
'pwd_abcdef',
'pwd_abc123',
];
var_dump(check_password_sequence($passwords[3], 4));
function check_password_sequence($password, $max) {
$j = 0;
$lenght = strlen($password);
for($i = 0; $i < $lenght; $i++) {
if(isset($password[$i+1]) && ord($password[$i]) + 1 === ord($password[$i+1])) {
$j++;
} else {
$j = 0;
}
if($j === $max) {
return true;
}
}
return false;
}

can this this strlen argument be used for validation?

I am new to PHP. My problem is I need the input to validate to a minimum 20 character input and return the last nine. Can anybody tell me if my argument is close to working and if not what do I need to do?
if (!empty($_POST['usen']) ||
strlen($usen['usen'] >= 20 )) {
$switch = substr($usen, -9, 9); // returns last nine of sentence
$output_form=false;
} else {
$error_text .="<p><span class='error'>*<strong>A Sentence of 20 char is required .</strong></span></p>";
$output_form=true;
}
You have several syntax problems and variable-naming problems. Your code should be:
if (!empty($_POST['usen']) && // || should be &&; the || doesn't make sense here
strlen($_POST['usen']) >= 20 ) { // You had $usen['usen'] and an incorrectly placed )
$switch = substr($_POST['usen'], -9); // again, this should be $_POST['usen'], not $usen. The third parameter is unnecessary here.
$output_form = false;
} else {
$error_text .= "<p><span class='error'>*<strong>A Sentence of 20 char is required .</strong></span></p>";
$output_form = true;
}
The key points:
You're using the wrong boolean operator. !empty($x) || strlen($x) >= 20 doesn't make sense. It should be &&, not ||. If you have a non-empty value for $_POST['usen'], then !empty($_POST['usen']) is true. But because you had a || in your if conditional, this meant the if block always executed for non-empty values, never the else block. You only want the if to execute if the value is non-empty and at least 20 characters.
Your variable is $_POST['usen'], but your code referred to $usen['usen'] and $usen, which are incorrect.
You had strlen($usen['usen'] >= 20) where you should have strlen($_POST['usen']) >= 20. Both the variable name and the ) placement were incorrect.
To get the last 9 characters of $usen['usen'] use
$switch = substr($usen, -9);
if (!empty($_POST['usen']) ||
strlen($_POST['usen']) >= 20 ) { // changed condition
$switch = substr($usen, -9, 9); // returns last nine of sentence
$output_form=false;
} else {
$error_text .="<p><span class='error'>*<strong>A Sentence of 20 char is required .</strong></span></p>";
$output_form=true;
}
The if-condition has two issues in second part
You use $usen['usen'] but i think it schould be $_POST['usen'] (see also comment by #Ed Cottrell)
The closing bracker from method-call strlen has to be after the param
if (!empty($_POST['usen']) &&
strlen($_POST['usen'] )>= 20 ) { //condition change
$switch = substr($_POST['usen'] ,-9); // returns last nine of sentence
$output_form=false;
} else {
$error_text .="<p><span class='error'>*<strong>A Sentence of 20 char is required .</strong></span></p>";
$output_form=true;
}
To get last 9 charcters , you can use substr(string, -9);

Count number of leading characters of a specific character at the beginning of a string?

Given a string such as:
$a = '00023407283';
$b = 'f045602345';
Is there a built in function that can count the number of occurrences of a specific character starting at the beginning and continuing until it finds a different character that is not specified?
Given the above, and specifying zero (0) as the character, the expected result would be:
$a = '00023407283'; // 3 (the other zeros don't count)
$b = 'f0045602345'; // 0 (It does not start with zero)
This should do the trick:
function count_leading($haystack,$value) {
$i = 0;
$mislead = false;
while($i < strlen($haystack) && !$mislead) {
if($haystack[$i] == $value) {
$i += 1;
} else {
$mislead = true;
}
}
return $i;
}
//examples
echo count_leading('aaldfkjlk','a'); //returns 2
echo count_leading('dskjheelk','c'); //returns 0
I don't think there's any built-in functions that could do that (it's too specific) but you could write a method to do that
function repeatChar($string, $char) {
$pos = 0;
while($string{$pos} == $char) $pos++;
return $pos;
}
Yes, you want strspn, which counts the number of characters from the second argument at the beginning of the first argument:
echo strspn($a, '0'); // === 3
echo strspn($b, '0'); // === 0
See it live at 3v4l.org. Besides being a built-in (read "fast"), this also accepts any number of single characters to look at the beginning. However, note that the function is byte-oriented, so it will not work as expected for multi-byte characters.

Filtering out double and triple digit numbers using php?

The question is pretty simple.
I am not quite clear with the regular expressions. Can this be done using regular expressions?
If the user enters double or triple digit number, echo This number cant be used.
If the user enters any other number, echo Go ahead.
There's no need for a regular expression.
if (!ctype_digit($target) || strlen($target) == 2 || strlen($target) == 3) {
# Number is invalid
}
$your_input = 123;
if (preg_match('/^[0-9]{2,3}$/', $your_input)) { // check if its double or three digit number
echo 'invalid input';
}
else {
echo 'valid input';
}
if (!is_numeric($str) || strlen($str) == 2 || strlen($str) == 3)
{
echo "This number cant be used";
}
else
{
echo "Go dhead";
}
Simple one liner...
echo strlen($yournumber)==2 || strlen($yournumber)==3 ? "Number cant be used" : "Go ahead";
try this
if(preg_match('/^\d{2,3}$/',$string)){ echo "valid";}else{echo "not valid";}
this will work for both conditions
$string = 111;
$string = "111";

Categories