PHP find double digit number before a given word - php

I need to find either a double or single-digit number that appears before a given word that is buried in a long string. For example find the number of children when given as follows:
Derive 12 from:
blah blah..................12 children............blah blah
or 6 from:
blah blah......6 children.............blah blah
The following code works for single digit but only returns 2 for the double digit
<?php
$body = ("..blah..blah...6 children....");
$children_single = explode ("children", $body);
$num_children = preg_replace("/[^0-9]/","", substr($children_single[0],-2));
echo $num_children;
?>
How do I adjust this to give both a single or double digit result?

Your current condition is failing because of the space. When you explode the string 12 children, the first part, $children_single[0], will contain the string 12 (note the space). So, when you use substr() on that string, the space will be included and will only capture 2 (with the space).
To avoid that, you can start substr() count from the beginning, by using the second parameter, like so:
$num_children = preg_replace("/[^0-9]/","", substr($children_single[0], 0, 2));
Demo!
UPDATE:
As per your comment, the above version won't work if the word children occurs in a long string. In that case, you can use a negative start, as follows:
$num_children = preg_replace("/[^0-9]/","", substr($children_single[0], -3, -1));
Demo!

Related

Return xx characters before a certain string

So I have this string:
Best location using 168 cars + cleaning
The '168' is the part i'd like to extract from this string.
I have approximately 80 occurences of this string, all alternating from 'xx' cars to 'xxx' cars (so, 2 or 3 numbers). However, in each string, 'cars' comes after the number i'd like to return.
What would be the best way using PHP to achieve this?
The best way is to do a simple preg_match on the text.
See the tutorial: http://php.net/manual/en/function.preg-match.php
<?php
$string = 'Best location using 168 cars + cleaning';
$pattern = '/(\d{2,3}+) cars/';
preg_match($pattern, $string, $match);
echo $match[1];
This regex returns all the numbers with length of 2 to 3 before the word cars.
you can change the length as you want and \d means all the numbers.
Easiest way is probably via preg_match(). Look for a space, one or more digits, a space, then the word cars. Use parens to capture the digits. That gives you pattern like this:
' (\d+) cars'
Then just pass that to preg_match() with a third argument to capture the parenthesized substring:
if (preg_match('/ (\d+) cars/', $str, $match)) {
echo "your num is: " . $match[1] . "\n";
}
Note this will also capture 1 cars and 1234 cars. If that's a problem, and you want to ensure that you only get the values with two or three digits, you can tweak the pattern to explicitly require that:
' (\d{2,3}) cars'
I would explode the string on a space and then loop through the array looking for the string "cars" and then get the key value for this. From here you know that the number will be before the "cars" occurrence so minus 1 from this key value and look in the array.
$original_string = "Best location using 168 cars + cleaning";
$string = explode(" ", $original_string);
foreach ($string as $key => $part) {
if($part == "cars") {
$number = $string[$key-1];
}
}
Explanation:
$original_string is whatever your whole string where the number is unknown.
$string is an array of the $original_string, each word will be in it's own part of the array
we loop through this array looking for the string "cars" and also get its key value.
If we find it successfully we then go to the key value minus one to find the number. We do this because we know the number appears before the "cars" string.

PHP how to get the second number present in a string

I would like to get the second number present in a string.
Maybe you have better ideas than mine.
From this example:
1 PLN = 0.07 Gold
I would like to get only "0.07" from that string.
I obtain it from web scraping so it returns me as a string.
The problem that I have is the following.
The "second number in string" might be with ".", without it, might be composed by only one number ex. "1", or by two "12", might have decimals ex. "1.2", even position may change, because for some currency I will have "1 PLN", "1 USD" for others I will have "1 TW".
So I can't work on position, I can't extract only numbers (I have the "1" at the beginning of the string), I can't extract only INT cause I could have also decimals...
So the only constant of that string - I think (but if you have better ideas pls suggest me) - is that I need the second number I find in the string.
How could I get it?
Sorry If I wasn't enough clear.
Try this:
<?php
$string = '1 PLN = 0.07 Gold';
$pattern = '/\d+\.\d+/';
$matches = array();
$r = preg_match($pattern, $string, $matches);
var_dump($matches); //$matches is array with results
Output:
array(1) {
[0]=>
string(4) "0.07"
}
If its always in this format 1 PLN = 0.07 Gold You can just
$array = explode(" ", $string) with a Space and then get the required number with
$number = $array[3]
Try it out, let me know if it works
You can use a simple regex patter to isolate all numbers, including decimals if any after the equals sign.
The below works if the string will have the same structure, meaning an = a space and then the number that you are after.
= - matches the equals sign
\s - matches the space character immediately after
(\d*\.?\d*) - matches any number of digits followed by an optional period . and then any number of digits
$str = '1 PLN = 0.07 Gold';
preg_match('#=\s(\d*\.?\d*)#',$str,$matches);
print $matches[1];
Will output
0.07
This works regardless of what you have before the = sign.

Remove characters from both left and right of a string in PHP

This is an example of a string: abcde123#ijklmn0pq
In that string I need to print out only the numbers (the 123 sequence), and remove the letters (from both left and right) and the hashtag (#) to be removed as well.
The hashtag (#) is always included in the string.
The hashtag (#) is always positioned to the right of the characters that need to be printed;
The hashtag (#) is always positioned to the left of the characters that need to be removed;
Therefore, the hashtag (#) can be used as a guide to remove the letters from the Right
The number of characters in the beginning is always equal to 5 (constant) (to be removed);
The number of characters in the middle is always different (variable) (to be printed);
The number of characters in the right is always different (variable) (to be removed);
Here's another string example, similar to the first one: !!##$IMPORTANT#=-=whatever
The characters that need to be printed are the word "IMPORTANT"
As with the first example, what's on the left side of the hashtag (#) needs to be printed, but it's important to print only the "IMPORTANT" word, without the special characters "!!##$".
$myString = '!!##$IMPORTANT#=-=whatever';
$result = substr($myString, 5, -1);
$pos = strpos($result, '#');
$result = substr($result, 0, $pos);
echo $result;
You can use regexes with preg_replace();
Assuming that the string you need to process is stored in $string:
preg_replace('^.{5}(.*)#.*$', '$1', $string);
https://www.regex101.com/r/hA8lY7/1
First pattern explanation:
^.{5}: matches any 5 character after the start of $string
(.*): matches any N character after (1) before the first occurence of # (first capturing-group)
#.*$: matches # and any N character after (2) before the end of $string
Second pattern explanation:
$1: replaces $string with the first capturing-group matched in the first pattern
Ill give a stab at this. seems pretty simple.
function choppy($choppy) {
$nstr = substr($choppy, 5,strlen($choppy)); //chop first 5
$pos = strpos($nstr, "#"); //Find the position of the hash tag
return substr($nstr, 0, $pos); //we only need the stuff before it...
}
echo choppy('!!##$IMPORTANT#=-=whatever');
echo "\n";
echo choppy('abcde123#ijklmn0pq');
Result
C:\Users\developer\Desktop>php test.php
IMPORTANT
123
The other answers are good but if you need a one-liner for your homework:
$str = '!!##$IMPORTANT#=-=whatever';
echo substr($str, 5, strpos($str, '#')-5); //IMPORTANT

Regular expression matching in php

I have this regexp:
/(.*)(([0-9]([^a-zA-Z])*){7,}[0-9])(.*)/.
Given the following values
0654535263
065453-.-5263
065asd4535263
Expected Results
06****
06****
06****
Actual Results
0654535263
06****
065asd4535263
It does not match the last row because of the letters (I want to match from 0-3 letters) and it matches only last occurence (in the second row in example, it skips first row).
First of all thank u all oyur answers are very helpfull and i owe u a bih time. I cant create array of numbers and mask them like that because i can have string like this:
I am John, I live bla bla my phone is: 0, 6, 5, 4, 5, 3, 5, 2, 6 - 3 -- 065asd4535263.
To simplify i want to hide entered mobile number.
I had two problems:
change regxp mentioned above, to hide digits separated by no more than 3 chars.
preg_replace was replacing only one occurence.
At the end i just need regexp to replace any array of digits, at least 6 digits long, separated by any number of special chars (12--654-5, 453/--222, 23....5645 etc) OR no more than 3 chars (ltters) (06asd453, 123as562).
Thank you again, all answers are vry helpfull, but i am gulty because i didnt formulated my question right.
p.s. i cant give u reputation because i must have at least 15, as soon as i get that much, i will 'vote up', all answers deserve it.
Hmm why so complicated when you only want to mascarade your string.
$input = '0654535263';
$input = substr($input, 0, 2);
$output = $input . '********';
Its a bit easier when you only want the first 2 characters of your string. Perhaps your solution had another sin. But this is a bit easier.
You can just use substr_replace
echo substr_replace($v, "****", 2);
Example
$list = array("0654535263","065453-.-5263","065asd4535263");
echo "<pre>";
foreach ( $list as $v ) {
echo substr_replace($v, "****", 2), PHP_EOL;
}
Output
06****
06****
06****
I'm guessing that the reason you want to use regular expressions is so that you don't mask every string that you get. This regex checks that there is at least 2 digits in the beginning of the string, then 0 to 3 alphabet characters, and then all the rest of the characters of the string need to be non-alphabet characters. If it matches, it masks the string, otherwise it says the string does not match.
$string = '0654535263';
if(preg_match('~^(\d{2})\d*?[a-zA-Z]{0,3}[^a-zA-Z]*$~', $string))
$answer = preg_replace('~^(\d{2})\d*?[a-zA-Z]{0,3}[^a-zA-Z]*$~', '$1****', $string);
else
$answer = $string . ' does not match';
print_r($answer); // 06****

Split alphanumeric string between leading digits and trailing letters

I have a string like:
$Order_num = "0982asdlkj";
How can I split that into the 2 variables, with the number as one element and then another variable with the letter element?
The number element can be any length from 1 to 4 say and the letter element fills the rest to make every order_num 10 characters long in total.
I have found the php explode function...but don't know how to make it in my case because the number of numbers is between 1 and 4 and the letters are random after that, so no way to split at a particular letter.
You can use preg_split using lookahead and lookbehind:
print_r(preg_split('#(?<=\d)(?=[a-z])#i', "0982asdlkj"));
prints
Array
(
[0] => 0982
[1] => asdlkj
)
This only works if the letter part really only contains letters and no digits.
Update:
Just to clarify what is going on here:
The regular expressions looks at every position and if a digit is before that position ((?<=\d)) and a letter after it ((?=[a-z])), then it matches and the string gets split at this position. The whole thing is case-insensitive (i).
Use preg_match() with a regular expression of (\d+)([a-zA-Z]+). If you want to limit the number of digits to 1-4 and letters to 6-9, change it to (\d+{1,4})([a-zA-Z]{6,9}).
preg_match("/(\\d+)([a-zA-Z]+)/", "0982asdlkj", $matches);
print("Integer component: " . $matches[1] . "\n");
print("Letter component: " . $matches[2] . "\n");
Outputs:
Integer component: 0982
Letter component: asdlkj
http://ideone.com/SKtKs
You can also do it using preg_split by splitting your input at the point which between the digits and the letters:
list($num,$alpha) = preg_split('/(?<=\d)(?=[a-z]+)/i',$Order_num);
You can use a regex for that.
preg_match('/(\d{1,4})([a-z]+)/i', $str, $matches);
array_shift($matches);
list($num, $alpha) = $matches;
Check this out
<?php
$Order_num = "0982asdlkj";
$split=split("[0-9]",$Order_num);
$alpha=$split[(sizeof($split))-1];
$number=explode($alpha, $Order_num);
echo "Alpha -".$alpha."<br>";
echo "Number-".$number[0];
?>
with regards
wazzy
My preferred approach would be sscanf() because it is concise, doesn't need regex, offers the ability to cast the numeric segment as integer type, and doesn't generate needless fullstring matches like preg_match(). %s does rely, though, on the fact that there will be no whitespaces in the letters segment of the string.
Demo
$Order_num = "0982asdlkj";
var_export (
sscanf($Order_num, '%d%s')
);
This can also be set up to declare individual variables.
sscanf($Order_num, '%d%s', $numbers, $letters)
If wanting to use a preg_ function, preg_split() is most appropriate, but I wouldn't use expensive lookarounds. Match the digits, then forget them (with \K). This will split the string without consuming any characters. Demo
var_export (
preg_split('/\d+\K/', $Order_num)
);
To assign variables, use "symmetric array destructuring".
[$numbers, $letters] = preg_split('/\d+\K/', $Order_num);
Beyond these single function approaches, there will be MANY two function approaches like:
$numbers = rtrim($Order_num, 'a..z');
$letters = ltrim($Order_num, '0..9');
But I wouldn't use them in a professional script because they lack elegance.

Categories