PHP preg_match + regex not identifying non-numeric input? - php

I'm trying to prevent non numbers from being inserted into my database, preferably not exceeding 6 digits. Currently my regex is failing to match and exit out of the PHP script if non-numeric characters are entered, and consequently, the data gets inserted into the database. I cannot figure out why, as its stated everywhere online that this solution should be correct. The data that's coming through is an array of characters, formed from an exploded string of those characters if that helps.
PHP:
for ($i = 0 ; $i <= $count ; ++$i)
{
if (!preg_match("/^\d+$/", $number_array[$i]))
{
exit();
}
else
{....

Without the loop, get all of the values that are numbers between 1 and 6 digits from the array into another array and then compare with the original array:
if(preg_grep('/^\d{1,6}$/', $number_array) != $number_array) {
exit;
} else {
//something
}
It's a bit longer, but you could also filter out the values that are not numbers between 1 and 6 digits and compare with the original:
(array_filter($number_array, function($v) {
return ctype_digit($v) && (strlen($v) < 7);
}) != $number_array)

This should be the regex you want, it matches all strings of numbers between 1 and 6 digits.
for ($i = 0 ; $i <= $count ; ++$i)
{
if (!preg_match("/^\d{1,6}$/m", $number_array[$i]))
{
exit();
}
else
{....
So 156546 will match but these won't.
1565467
156546s
s15654
156546sa
asdfasdfa

Related

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;
}

How can I solve this Possible three letter words

I want to solve this problem of Possible three letter words
Here is following words. (17 characters)
19920620forestJSR
How many possible ways to make 3 length word with given characters?
Ex: 192, 162, Rer, ….
Rule:
Number 0 is different alpha o. (0 != o)
case-sensitive is available. (R != r)
same character repeat not available. (rr1 : wrong)
Hint:
17 16 15 : wrong
How can I solve this
I am trying with this code
function permute($str,$i,$n) {
if ($i == $n)
print "$str\n";
else {
for ($j = $i; $j < $n; $j++) {
swap($str,$i,$j);
permute($str, $i+1, $n);
swap($str,$i,$j); // backtrack.
}
}
}
function swap(&$str,$i,$j) {
$temp = $str[$i];
$str[$i] = $str[$j];
$str[$j] = $temp;
}
$str='19920620forestJSR';
permute($str,0,strlen($str));
But in output have some error with numeric characters
Output look like (when str=19920620forestJSR)
n���Z��뢿�Yh��fzj+�ȳz��ߍ�シo+^��aj�-y�k��m��e�ƭ{�6�ټ�zȧo�h���j���Z�ǫ���������z�a���X�y�����
Output look like (when str=forestJSR)
foresSJtR
foresSJRt
foresStJR
foresStRJ
foresSRtJ
foresSRJt
foresRJSt
foresRJtS
The rules says you need combinations of 3 characters, whithout repeating letters. Your code is generating all combinations for 17 letters. So, the script is looping for millions of possibilities (355,687,428,096,000).
The number of permutations of n distinct objects, taken r at a time is
nPr = n! / (n - r)!
So, for "19920620forestJSR" (14 different letters only), using 3 at a time:
14P3 = 14! / (14 - 3)! = 14! / 11! = (14)(13)(12) = 2184

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.

Select random strings over 6 and under 10 characters from text file

I have a text file, and I need to pick a random string that is over 6 characters and under 10 characters. Normally, I would use a script like this, which would work, but since it needs to be a certain length, that won't work. Does anybody have a solution to this?
A sample input would be something like this:
Apple
Banana
Orange
Strawberry
Blueberry
Pineapple
Somelongfruithere
Those values would be in a .txt file, each with a line break. An example of a string that would be allowed is pineapple, but apple or Somelongfruithere wouldn't be allowed.
You'll need to do something like this:
$lines = array();
$tmpLines = file('random.txt');
for($i = 0; $i < count($tmpLines); ++$i)
{
if(strlen($tmpLines[ $i ]) > 6 && strlen($tmpLines[ $i ]) < 10)
{
$lines[] = $tmpLines[ $i ];
}
}
$randomWord = $lines[ array_rand($lines) ];
A shorter way, in number of lines, goes like this (but is much less safe):
$randomWord = '';
$lines = file('random.txt');
while(strlen($randomWord) <= 6 || strlen($randomWord) >= 10)
$randomWord = $lines[ array_rand($lines) ];
The first option gets all the lines in the file, and copies only the ones between 6 and 10 chars in length to another array. When choosing a random element from this array, you are "guaranteed" a reasonable access time for any random string.
The second option simply continues to pick a random string until one of the proper length is chosen, but could potentially take a while depending on the random number generator's mood. Unlikely, but I wouldn't want to risk it. Always take reliability as the best approach, in my book.
I would say explode the text file into a variable, run your random generator to get a placement value (position of the random string) then in a loop (a do/while loop), pull the string from the exploded variable, and check it's length to ensure it's what you want
if (strlen($rand_word) > 6 && strlen($rand_word) < 10) {
//execute function and end loop
} else {
// keep checking using a new random placement number
}
The answer depends on the requirement.
If you need to select from a group of strings and only accept one that fits your criteria, then you'll need to use strlen and try again if it is not the correct length.
Otherwise, you're still going to need strlen, to make sure it is at least 6 Chars, but then you can use substr to cut it to 10. If whitespace does not count, use ltrim & rtrim before strlen and substr.
First find all the words that are in the right character range, then pull a random one from the resulting array:
$fileLines = file('somefile.txt');
$myWords = array();
foreach ($fileLines as $line)
{
$thisLine = split(" ",$line);
foreach ($thisLine as $word)
{
$length = strlen($word);
if ($length > 6 && $length < 10)
{
$myWords[] = $word;
}
}
}
$randomWord = $myWords[array_rand($myWords)];
Shortened way!
for ($i=7; $i<=9; $i++)
if (strlen($str) == $i )
echo "bingo! " . strlen($str);

php's preg_match returning different number of matches for same pattern

I'm trying out preg_match with a roman numeral to integer converter. The problem is, for certain inputs, preg_replace seems to be giving too few matches. The code:
function romanNumeralToInt($romanNumeral)
{ preg_match
( '/^(M?M?M?)'
.'((CM)|(CD)|((D?)(C?C?C?)))'
.'((XC)|(XL)|((L?)(X?X?X?)))'
.'((IX)|(IV)|((V?)(I?I?I?)))$/', $romanNumeral, $match);
print_r($match);
$result=0;
$result += 1000*strlen($match[1]);
if(strlen($match[3]) != 0){$result += 900;}
if(strlen($match[4]) != 0){$result += 400;}
if(strlen($match[5]) != 0)
{ $result += 100*strlen($match[7]) + 500*strlen($match[6]);
}
if(strlen($match[9]) != 0){$result += 90;}
if(strlen($match[10]) != 0){$result += 40;}
if(strlen($match[11]) != 0)
{ $result += 10*strlen($match[13]) + 50*strlen($match[12]);
}
if(strlen($match[15]) != 0){$result += 9;}
if(strlen($match[16]) != 0){$result += 4;}
if(strlen($match[17]) != 0)
{ $result += 1*strlen($match[19]) + 5*strlen($match[18]);
}
return $result;
}
echo romanNumeralToInt("XXVIII"); // gives correct results
But any roman numeral ending in "IV" will cut off the last 3 matches ($matches will only contain elements 0-16 rather than the full 0-19), and similarly any roman numeral ending in "IX" will cut off the last 4 matches.
Is this expected behavior, or is my PHP buggy?
I expect this to be expected behavior. =)
Regex tries to match OR groups from left to right, stopping as soon as it finds a match, so it will never try to match those last three (or four) groups if it finds a IV or IX.
Actually, I think that, if your expression contains a CM or XL or something like that, some of the other entries will be missing, too.
I find that using RegExr helps a lot with debugging regular expressions. Using this for your regex, some groups catch empty strings, and some groups contain NO MATCH.

Categories