Check if a String Ends with a Number in PHP - php

I'm trying to implement the function below. Would it be best to use some type of regex here? I need to capture the number too.
function endsWithNumber($string) {
$endsWithNumber = false;
// Logic
return $endsWithNumber;
}

return is_numeric(substr($string, -1, 1));
This only checks to see if the last character in the string is numerical, if you want to catch and return multidigit numbers, you might have to use a regex.
An appropriate regex would be /[0-9]+$/ which will grab a numerical string if it is at the end of a line.

$test="abc123";
//$test="abc123n";
$r = preg_match_all("/.*?(\d+)$/", $test, $matches);
//echo $r;
//print_r($matches);
if($r>0) {
echo $matches[count($matches)-1][0];
}
the regex is explained as follows:
.*? - this will take up all the characters in the string from the start up until a match for the subsequent part is also found.
(\d+)$ - this is one or more digits up until the end of the string, grouped.
without the ? in the first part, only the last digit will be matched in the second part because all digits before it would be taken up by the .*

To avoid potential undefined index error use
is_numeric($code[strlen($code) - 1])
instead.

in my opinion The simple way to find a string ends with number is
$string = "string1";
$length = strlen($string)-1;
if(is_numeric($string[$length]))
{
echo "String Ends with Number";
}

Firstly, Take the length of string, and check if it is equal to zero (empty) then return false. Secondly, check with built-in function on the last character $len-1.
is_numeric(var) returns boolean whether a variable is a numeric string or not.
function endsWithNumber($string){
$len = strlen($string);
if($len === 0){
return false;
}
return is_numeric($string[$len-1]);
}
Tests:
var_dump(endsWithNumber(""));
var_dump(endsWithNumber("str123"));
var_dump(endsWithNumber("123str"));
Results:
bool(false)
bool(true)
bool(false)

This should work
function startsWithNumber(string $input):bool
{
$out = false; //assume negative response, to avoid using else
if(strlen($input)) {
$out = is_numeric($input[0]); //only if string is not empty, do this to avoid index related errors.
}
return $out;
}

Related

PHP - Check for leading 0's in 2 comma-delimited integers

I have a user-input string with 2 comma-delimited integers.
Example (OK):
3,5
I want to reject any user input that contains leading 0's for either number.
Examples (Bad):
03,5
00005,3
05,003
Now what I could do is separate the two numbers into 2 separate string's and use ltrim on each one, then see if they have changed from before ltrim was executed:
$string = "03,5";
$string_arr = explode(",",$string);
$string_orig1 = $string_arr[0];
$string_orig2 = $string_arr[1];
$string_mod1 = ltrim($string_orig1, '0');
$string_mod2 = ltrim($string_orig2, '0');
if (($string_mod1 !== $string_orig1) || ($string_mod2 !== $string_orig2)){
// One of them had leading zeros!
}
..but this seems unnecessarily verbose. Is there a cleaner way to do this? Perhaps with preg_match?
You could shorten the code and check if the first character of each part is a zero:
$string = "03,5";
$string_arr = explode(",",$string);
if ($string_arr[0][0] === "0" || $string_arr[1][0] === "0") {
echo "not valid";
} else {
echo "valid";
}
Here is one approach using preg_match. We can try matching for the pattern:
\b0\d+
The \b would match either the start of the string, or a preceding comma separator.
If we find such a match, it means that we found one or more numbers in the CSV list (or a single number, if only one number present) which had a leading zero.
$input = "00005,3";
if (preg_match("/\b0\d+/", $input)) {
echo "no match";
}
You can do a simple check that if the first character is 0 (using [0]) or that ,0 exists in the string
if ( $string[0] == "0" || strpos($string, ",0") !== false ) {
// One of them had leading zeros!
}
All the current answers fail if any of the values are simply 0.
You can just convert to integer and back and compare the result.
$arr = explode(',', $input);
foreach($arr as $item) {
if( (str)intval($item) !== $item ) {
oh_noes();
}
}
However I am more curious as to why this check matters at all.
One way would be with /^([1-9]+),(\d+)/; a regex that checks the string starts with one or more non-zero digits, followed by a comma, then one or more digits.
preg_match('/^([1-9]+),(\d+)/', $input_line, $output_array);
This separates the digits into two groups and explicitly avoids leading zeros.
This can be seen on Regex101 here and PHPLiveRegex here.

PHP: Regex, must contain all letters from list

Does anyone know how to write regex pattern, that does this:
let's say I have letters in array like
$letters = array('a','b','a');
and also we have a word Alabama and I want preg_match to return true, since it contains letter A two times and B. But it should return false on word Ab, because there aren't two A in that word.
Any ideas ?
EDIT: the only pattern I tried was [a,b,a] but it returns true on every word that does contain one of these letters and also doesn't check it for multiple letter occurences
I think you don't have to overcomplicate the process. You can traverse the letters and check if the exists in the word, if all the letter are there, return true. Something like this:
$letters = array('a','b','a');
$word = "Alabama";
function inWord($l,$w){
//For each letter
foreach($l as $letter){
//check if the letter is in the word
if(($p = stripos($w,$letter)) === FALSE)
//if false, return false
return FALSE;
else
//if the letter is there, remove it and move to the next one
$w = substr_replace($w,'',$p,1);
}
//If it found all the letters, return true
return TRUE;
}
And use it like this: inWord($letters,$word);
Please note this is case insensitive, if you need it case sensitive replace stripos by strpos
Must you need to use regular expressions? Even if the problem can be solved through them, the code will be very complicated.
"Manual" solution will be clearer and takes linear time:
function stringContainsAllCharacters(string $str, array $chars): bool
{
$actualCharCounts = array_count_values(str_split($str));
$requiredCharCounts = array_count_values($chars);
foreach ($requiredCharCounts as $char => $count) {
if (!array_key_exists($char, $actualCharCounts) || $actualCharCounts[$char] < $count) {
return false;
}
}
return true;
}

Check if string is a comma-separated list of digits

In my table1 i have varchar field where i store an id-list of other table2 (id - INT UNSIGNED AUTOINCREMENT), separated by comma.
For example: 1,3,5,12,90
Also ids should not be repeated.
I need to check if a string (coming from outside) matches this rule.
For example i need to check $_POST['id_list']
Data consistency is not important for now (for example insert this value without checking if this ids really exist in table2)
Any advice will be helpful.
The easiest way to do such check is to use regular expression (preg_match).
Lets try to find a pattern matching our rule.
Just comma-separated digits:
^[0-9]+(,[0-9]*)*$
^ - means start of string.
$ - means end of string.
[0-9]+ - means that our string MUST starts with a digits.
(,[0-9]+)* - means that our string CAN continue itself with ",$someDigits" manner, from 0 to as many you wish times.
But if our digits are "INT UNSIGNED AUTOINCREMENT" we should modify our pattern this way:
^[1-9][0-9]*(,[1-9][0-9]+)*$
to exclude cases like: 0,01,02,009,000,012
As for unique values, i think more clear will be to use splitting (explode) string by comma to array, pass it through array_unique and compare.
So the result check-function will be:
function isComaSeparatedIds($string, $allowEmpty = false) {
if ($allowEmpty AND $string === '') {
return true;
}
if (!preg_match('#^[1-9][0-9]*(,[1-9][0-9]*)*$#', $string)) {
return false;
}
$idsArray = explode(',', $string);
return count($idsArray) == count(array_unique($idsArray));
}
Also added $allowEmpty argument if u would like to allow empty strings.
For the sake of completeness I would like to mention the following solution:
<?php
$check = explode(',', $string);
if ($diff = array_diff_key($check, array_filter($check, 'ctype_digit'))) {
// at least one is not a digit
foreach ($diff as $failIndex => $failValue) {
// handle
}
}
For less than 1000 digits in the string this is a little faster than preg_match and as little extra you get the positions and the values that are not a digit.
This is a bit of a cheeky solution,but it sure does the work.
<?php
$a="1,3,5,12,90";
$b=explode(",",$a);
$str='';
for($c=0;$c<count($b);$c++)
{
if (preg_match('/^[0-9]+$/', $b[$c]))
{
$str=$str."Y";
}
}
if(count(array_unique($b))==count($b) && (count($b)==strlen($str)))
{
echo $str;
//FURTHER CODE HERE WHEN ALL ELEMENTS UNIQUE AND VALID NUMBERS
}
else
{
//FURTHER CODE HERE WHEN NOT UNIQUE OR NOT A VALID NUMBERS
}
?>

exact preg_match with #

How can I preg_match exactly with that kind of search:
My value to find: #5#
My value to search: #5#;#9#
I did a simple
if (preg_match("#5#", "#5#;#9#")) { return true; } else { return false; }
And, it returns true.
The problem with that code, it's return also true if my value to compare is #51#;#55# whereas it has to be false in that case:
if (preg_match("#5#", "#51#;#55#")) { return true; } else { return false; }
Also returns true whereas I want false.
preg_match("#5#", "#51#;#55#") returns true because preg_match uses # as delimiter. In order to match #5# you have to add delimiters around the regex:
if (preg_match("/#5#/", "#51#;#55#")) { return true; } else { return false; }
This will return false.
If all you need is to find a string you know (#5#) in another string then the best way is to use function strpos(). It returns the boolean FALSE if it cannot find the string or an integer number that represents the position of the searched string into the other string.
It is faster that any preg_*() function.
$pos = strpos('#5#', '#5#;#9#');
if ($pos !== FALSE) {
echo('Found (at position '.$pos.')');
} else {
echo('Not found.');
}
You have to pay attention to the comparison operator: using $pos != FALSE is not enough because 0 == FALSE. You have to compare using === or !== to avoid this.
Using preg_match()
Your approach failed because in PHP the PCRE functions interpret the first character from the regex as a delimiter.
This means the regex in #5# is: 5. And this regex, of course, matches any 5 it finds in the string. To fix it you have to surround your regex with some delimiter (/ is usually used):
return preg_match('/#5#/', '#5#;#9#');

php regex question - test 10 digits long with first 5 same digit and second 5 another

I'm trying to port this java to php:
String _value = '1111122222';
if (_value.matches("(1{5}|2{5}|3{5}|4{5}|5{5}|6{5}|7{5}|8{5}|9{5}){2}")) {
// check for number with the same first 5 and last 5 digits
return true;
}
As the comment suggests, I want to test for a string like '1111122222' or '5555566666'
How can I do this in PHP?
Thanks,
Scott
You can use preg_match to do so:
preg_match('/^(1{5}|2{5}|3{5}|4{5}|5{5}|6{5}|7{5}|8{5}|9{5}){2}$/', $_value)
This returns the number of matches (i.e. either 0 or 1) or false if there was an error. Since the String’s matches method returns only true if the whole string matches the given pattern but preg_match doesn’t (a substring suffices), you need to set markers for the start and the end of the string with ^ and $.
You can also use this shorter regular expression:
^(?:(\d)\1{4}){2}$
And if the second sequence of numbers needs to be different from the former, use this:
^(\d)\1{4}(?!\1)(\d)\2{4}$
Well, you could do:
$regex = '/(\d)\1{4}(\d)\2{4}/';
if (preg_match($regex, $value)) {
return true;
}
Which should be much more efficient (and readable) than the regex you posted...
Or, an even shorter (and potentially cleaner) regex:
$regex = '/((\d)\2{4}){2}/';
$f = substr($_value, 0, 5);
$s = substr($_value, -5);
return (substr_count($f, $f[0]) == 5 && substr_count($s, $s[0]) == 5);
Conversion is below. preg_match() is the key: http://www.php.net/preg_match
$value = '1111122222';
if (preg_match('/^(1{5}|2{5}|3{5}|4{5}|5{5}|6{5}|7{5}|8{5}|9{5}){2}$/', $value)) {
// check for number with the same first 5 and last 5 digits
return true;
}

Categories