php regex for min and max number length - php

if(strlen(trim($steamid)) != 0)
{
$regex = "/^STEAM_0:(0|1):[0-9]{1}[0-9]{0,8}$/";
if(!ereg($regex, $ssteamid)){
echo "STEAM ID invalida";
}
}
My problem is that this isn't working as it should.
STEAM ID's have maximum of 18 characters and minimum of 17.
they always start with: STEAM_0:
Two true examples would be: STEAM_0:0:11111111 ; STEAM_0:1:1111111
And another thing is that after STEAM_0: always come an 0 or an 1 like demonstrated in the examples.

This:
$regex = "/^STEAM_0:(0|1):[0-9]{1}[0-9]{0,8}$/";
could be writter shorter as:
$regex = "/^STEAM_0:[01]:[0-9]{1,9}$/";
Since your ID is 17 or 18 chars long, adjust the regex to it:
$regex = "/^STEAM_0:[01]:[0-9]{7,8}$/";
Finally, note that ereg is deprecated as of PHP 5.3. This snippet shows your php/regex with preg_match:
<?php
$steamid = "STEAM_0:0:11111111";
if(strlen(trim($steamid)) != 0)
{
$regex = "/^STEAM_0:[01]:[0-9]{7,8}$/";
if(!preg_match($regex, $steamid))
{
echo "STEAM ID invalida.\n";
} else {
echo "STEAM ID valida.\n";
}
}
?>

If the minimum length is 17 and the max length is 18, then you guys are looking at this at the wrong way.
This should do the job for you:
$regex = "/^STEAM_0:(0|1):[0-9]{7}[0-9]?$/";
And also, when in doubt, test your regexp with some of the online regexp tools like http://www.regexplanet.com/simple/index.html

Try this:
$regex = "/^STEAM_0:(0|1):[0-9]{8,9}$/";
It matches:
STEAM_0: at the beginning, followed
by
a 0 or a 1, followed by a :,
followed by
Either 8 or 9 digits, making the
total number of characters 17 or 18

You should be avoiding use of ereg() and its related functions; they've deprecated for quite a long time in PHP. Use thepreg_xx() functions instead (preg_match() in this case).
One of the differences between preg_match() and ereg() is that ereg() does not expect you to include the slash characters to start and end the regex, whereas preg_match() does. This is probably the main reason your code isn't working: since you've included the slashes, your use of ereg() won't work, but is you switch to preg_match(), the same expression should work fine.
So a simple change to preg_match() should sort you problem. But while I'm here, I may also suggest that you can shorten your regex string quite considerably. Try something like this:
$regex = "/^STEAM_0:[01]:[0-9]{8,9}$/";
if(!preg_match($regex, $ssteamid)) {
echo "STEAM ID invalid";
}
Hope that helps.

Related

Regular expression returns empty array in php even though the regular expression is correct

This is my regular expression:
$pattern_new="/<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(?<price>([0-9.]*)).*?)\$(.*?)(\n|\s)*?</";
This is the sample pattern from which I have to do a match:
<td><strong>.zx</strong></td><td><span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s $399</td><td>zxcddcdcdcdc</td></tr><tr class="dark"><td><strong>.aa.rr</strong></td><td><span class="offer"><strong>xscre:<br></strong>$99 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&eae;s $199</td><td>xxxx</td></tr><tr class="bar"><td colspan="3"></td></tr><tr class="bright"><td><strong>.vfd</strong></td><td><span class="offer"><strong>xscre:<br></strong>$99 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>du&ee;s $199</td><td>xxxxxxxx</td></tr><tr class="dark"><td><strong>.qwe</strong></td><td><span class="offer"><strong>xxx<br></strong>$99 xxxc;o<span class="fineprint_number">2</span>
Here is what I am doing in PHP
$pattern_new="/<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(<price>)*([0-9.]*).*?)\$(.*?)(\n|\s)*?</";
$source = file_get_contents("https://www.abc.com/sources/data.txt");
preg_match_all($pattern_new, $source, $match_newprice, PREG_PATTERN_ORDER);
echo$source;
print_r($match_newprice);
the$match_newprice is returning an empty array.
When I am using a regex tester like myregextester or solmetra.com I am getting a perfect match no issues at all but when I am using php preg_match_all to do the match it is returning an empty array. I increased the pcre.backtrack_limit but its still the same issue.
I don't seem to understand the problem. Any help would be much appreciated.
I assume you were trying to do a noncapture group for <price... but you missed the :. Or you should take out the question mark. If the price group is optional, try like the regex below. You should use the following website to help you with regex. I find it extremely helpful.
<td>(\n|\s)*?(<span(\n|\s|.)*?<\/strong>(\n|\s)*?\$(<price>)*([0-9.]*).*?)\$(.*?)(\n|\s)*?<
Edit live on Debuggex
In the above example, your first match would have the following captures:
0: "<td><span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s $399<"
1: ""
2: "<span class="offer"><strong>xscre:<br></strong>$299 xxxxx&x;xx<span class="fineprint_number">2</span></span><br>de&ea;s "
3: ">"
4: ""
5: ""
6: "299"
7: "399"
8: ""
Is this what you are looking for?
Another problem which is PHP related with this:
<?php
echo "\$".PHP_EOL;
echo '\$'.PHP_EOL;
Result:
$
\$
... as in double quoted strings the $ is expected to signify the start of a variable, and needs escaping if you mean a bare $. Put single quotes around your regex & it will probably be fine (haven't looked at in detail though, you may want to use the /x option & add some formatting whitespace/comments if you need to debug this a half year from now).
The good way to do that:
$oProductsHTML = new DOMDocument();
#$oProductsHTML->loadHTML($sHtml);
$oSpanNodes = $oProductsHTML->getElementsByTagName('span');
foreach ($oSpanNodes as $oSpanNode) {
if (preg_match('~\boffer\b~', $oSpanNode->getAttribute('class')) &&
preg_match('~\$\K\d++~', $oSpanNode->nodeValue, $aMatch) )
{
$sPrice = $aMatch[0];
echo '<br/>' . $sPrice;
}
}
$sHtml stands for your string.
And i'm sure you can make it shorter with XPath.
The bad way:
$sPattern = '~<span class="offer\b(?>[^>]++|>(?!\$))+>\$\K\d++~';
preg_match_all($sPattern, $sHtml, $aMatches);
print_r ($aMatches[0]);
Notice: \d++ can be replaced by \d++(?>\.\d++)? to allow decimal numbers.

PHP Regex - Value of 1 or more integers [duplicate]

This question already has answers here:
php validate integer
(7 answers)
Closed 9 years ago.
Hey I'm trying to perform input validation in PHP to ensure that the stock values that are typed in are at least 1 positive integer and from 0-9. Should not contain any special characters.
For example, any of the following values should be valid:
7
0
32
47534
The following SHOULD NOT be valid:
asdf
35/gdf
../34.
etc..
I'm using the following if statement to check for the positive integer value of "$original_stock".
if (preg_match("/^[0-9]$/", $original_stock))
{
$error .="Original stock must be numerical.";
}
Additionally, I have a price field which should be validated as either an int or a double.
If there's an easier alternative to using regex, that's okay too!
Thanks in advance :)
Try this regexp:
/^\d+$/
The issue with your existing regexp is that it only matches strings with exactly one digit.
As for validating an int or a double:
/^\d+\.?\d*$/
Note that that regexp requires that there be at least one digit.
Use:
/^[0-9]+$/
The + means "one or more". Without it, your regex will only match a single digit. Or you could use the simpler variant:
/^\d+$/
For floats, try something like:
/^\d+(\.\d{1,2})?/
This will match one or more digits, optionally followed by a . and one or two digits. (i.e. .12 will not match.)
To save yourself some headaches, you can also use the is_int and is_float functions.
Lastly; note that your check is wrong. preg_match will return 0 if it fails, so you should write it as:
if (!preg_match("/^\+$/", $original_stock)) {
// error
}
(note the !).
You may want to use the
is_int
Don't reinvent a wheel slower than an existing one, use a motorcycle: is_int.
#Assuming $original_stock is a single value...
if (is_int($original_stock)) {
#Valid, do stuff
}
else {
#Invalid, do stuff
}
#Assuming $original_stock is an array...
$valid = true;
foreach ($original_stock as $s) {
if (!is_int($s)) {
$valid = false;
break;
}
}
if ($valid) {...}
else {...}
I just ran into this exact problem and solved it this way using the regex.
I think the problem is your caret ^.
/^[0-9]$/
I moved it inside the class and got the results I needed.
function validate_int($subject)
{
//Pattern is numbers
//if it matches anything but numbers, we want a fail
$pattern = '/[^0-9]/';
$matches = preg_match($pattern, $subject);
if($matches > 0)
return false;
else
return true;
}

Filter out numbers in a string in php

assuming i have these texts 'x34' , '150px' , '650dpi' , 'e3r4t5' ... how can i get only numbers ? i mean i want 34 , 150 , 650 , 345 without any other character . i mean get the numbers this string has into one variable .
$str = "e3r4t5";
$str_numbers_only = preg_replace("/[^\d]/", "", $str);
// $number = (int) $str;
Sorry for joining the bandwagon late, rather than using Regex, I would suggest you use PHP's built in functions, which may be faster than Regex.
filter_var
flags for the filters
e.g. to get just numbers from the given string
<?php
$a = '!a-b.c3#j+dk9.0$3e8`~]\]2';
$number = str_replace(['+', '-'], '', filter_var($a, FILTER_SANITIZE_NUMBER_INT));
// Output is 390382
?>
To adhere to more strict standards for your question, I have updated my answer to give a better result.
I have added str_replace, as FILTER_SANITIZE_NUMBER_FLOAT or INT flag will not strip + and - chars from the string, because they are part of PHP's exception rule.
Though it has made the filter bit long, but it's now has less chance of failing or giving you unexpected results, and this will be faster than REGEX.
Edit:
1: Realized that with FILTER_SANITIZE_NUMBER_FLOAT, PHP won't strip these characters optionally .,eE, hence to get just pure numbers kindly use FILTER_SANITIZE_NUMBER_INT
2: If you have a PHP version less than 5.4, then kindly use array('+', '-') instead of the short array syntax ['+', '-'].
You can use a regular expression to remove any character that is not a digit:
preg_replace('/\D/', '', $str)
Here the pattern \D describes any character that is not a digit (complement to \d).
Use PHP FILTER functions if you are using PHP 5.2.X, 5.3.x,5.4 . Its highly recommended
$mixed_input = "e3r4t5";
$only_numbers = filter_var($mixed_input, FILTER_SANITIZE_NUMBER_INT);
Please Go through with this link to know more
Replace everything that isn't a number and use that value.
$str = "foo1bar2baz3";
$num = intval(preg_replace("/[^0-9]/", "", $str));
You could use the following function:
function extract_numbers($string) {
preg_match_all('/([\d]+)/', $string, $match);
return $match;
}

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

check for number anywhere in a string

$vari = "testing 245";
$numb = 0..9;
$numb_pos = strpos($vari,$numb);
echo substr($vari,0,$numb_pos);
The $numb is numbers from 0 to 9
Where am I wrong here, all I need to echo is testing
You want to cut out the numbers from a string?
$string = preg_replace('/(\d+)/', '', 'String with 1234 numbers');
Use a regular expression to strip numeric characters from your string.
or, use a regular expression to find the first instance of one either way...
Your code won't work as-is, as it'll fail if the number if the first character in the string. (You need to check $numb_pos !== false prior to the substr.)
Irrespective, if you just want to check for the existance of a number in a string, something like the following would probably be more efficient.
$digitMatched = preg_match('/\\d/im', $vari);

Categories