Regular expression pattern to distinguish these texts - php

I have the below text, and I want a regular expression pattern for it:
qos policy 1024SharedUnlimitedUserRX pwfq
rate maximum 1792
weight 16
num-queues 4
queue-map Fastweb
congestion-map Fastweb
queue 0 priority 0 weight 100
queue 1 priority 1 weight 90
queue 2 priority 2 weight 70
queue 3 priority 3 weight 85
The pattern should fetch the integer value after the first weight phrase. In other words I want the 16 value, but not value of the next 4 lines(100, 90, 70, 85).
I wrote this pattern:
/weight (\d*)/
but this pattern found value of the other lines too, what should I do?
Note: I used preg_math() function, not preg_match_all()

This regex would perhaps suit you:
preg_match('/^weight (\d+)/m', $input, $match);
regex101 demo
^ makes sure that the weight is at the beginning of the line.
The m flag makes ^ match at the beginning of each line instead of only at the beginning of the string.
If there can be other weight you don't want which can be at the beginning of the line, you can try this instead, which makes sure that the weight is just after maximum:
preg_match('/maximum \S*\s*weight (\d+)/m', $input, $match);
regex101 demo

Do like this
<?php
$input_line="qos policy 1024SharedUnlimitedUserRX pwfq
rate maximum 1792
weight 16
num-queues 4
queue-map Fastweb
congestion-map Fastweb
queue 0 priority 0 weight 100
queue 1 priority 1 weight 90
queue 2 priority 2 weight 70
queue 3 priority 3 weight 85";
preg_match("/(?:weight\s(\d+)(?!\S+))/", $input_line, $output_array);
print_r($output_array);
DEMO
OUTPUT
Array
(
[0] => weight 16
[1] => 16
)

You can use this regex
(?<=weight )\d+
Check the regex at http://regex101.com/r/eP2yS2
DEMO
<?php
$input_line="qos policy 1024SharedUnlimitedUserRX pwfq
rate maximum 1792
weight 16
num-queues 4
queue-map Fastweb
congestion-map Fastweb
queue 0 priority 0 weight 100
queue 1 priority 1 weight 90
queue 2 priority 2 weight 70
queue 3 priority 3 weight 85";
preg_match("/(?<=weight )\d+/", $input_line, $output_array);
print_r($output_array);
?>
OUTPUT
Array
(
[0] => 16
)
Link : https://eval.in/109758

rate maximum \d+[\s\S]+?weight \d+

Related

How Do I Implement Incomplete Answer to Old Question

This comment looks like it would work if the author included the value for $numbers. They say it is some type of array, but don't provide enough information to replicate it. I picture some hard coded array ranging from 0 to 9, but I can't help think that such an array would miss numbers greater than 9. What does the numbers array in this example look like?
$text = "1 out of 23";
if(preg_match_all('/\d+/', $text, $numbers))
$lastnum = end($numbers[0]);
I would just post a comment asking whoever wrote that to paste the value for $numbers, but it says I need reputation points to do that.
See How do I grab last number in a string in PHP?
To answer your initial question print_r() can be used to output all contents of an array. e.g. print_r($numbers)
https://3v4l.org/2jA1b
To explain the code:
\d is a single number
+ is a quantifier meaning one or more of the previous character or group
so this would find all numbers in a string. The $numbers[0] would be all numbers, 1 per index, and the end() pulls to the last number/index. Each index would be a number, the 0 is all matches, each indice at the root level is a capture group.
This code wouldn't work as intended for decimals or comma delimited integers. In those cases the numbers would be split up at the delimiter. 1.0 would become 1 and 0 (2 different numbers).
You could rewrite this as:
$text = "1 out of 23";
if(preg_match('/.*\K\D\d+/', $text, $numbers))
echo $numbers[0];
so the end function is not needed. This pulls everything until the last number then forgets everything before the last number.
What you are trying to do is likely easier using preg_split instead of preg_match_all. We can split the input text by the matched regex (digits) and then rebuild the string while incrementing the numbers as we go.
<?php
function incrementNumbers($text) {
// NOTES:
// parenthesis are important in the regex in order to return the captured values
// the -? will capture negative numbers too if necessary
// PREG_SPLIT_DELIM_CAPTURE allows the captured values to be returned too
$split = preg_split('/(-?\d+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$return = '';
foreach($split as $i => $s) {
// because we didn't use PREG_SPLIT_NO_EMPTY, $split[0] will either be an empty string if
// $text began with a number, or the text before the first number. Either way, $split alternates
// between non-number [0], number [1], non-number [2], number [3], etc which is why we can detect
// even or odd indexes to determine if this is a number that needs to be incremented or not
if ($i % 2 === 0) {
$return .= $s;
} else {
$return .= (intval($s) + 1);
}
}
return $return;
}
Examples:
echo incrementNumbers("1 out of 23 with 1 and 1 and 24 and 23");
echo incrementNumbers("1 1 2 2 3 3 2 2 1 1");
echo incrementNumbers("0 1 2 3 4 5 6 7");
echo incrementNumbers("-3 -2 -1 0 1 2 3 4 5 6 7");
echo incrementNumbers("there are no numbers in this text");
echo incrementNumbers("does not start 999 with a number 123 nor end 17 with a number");
Outputs:
2 out of 24 with 2 and 2 and 25 and 24
2 2 3 3 4 4 3 3 2 2
1 2 3 4 5 6 7 8
-2 -1 0 1 2 3 4 5 6 7 8
there are no numbers in this text
does not start 1000 with a number 124 nor end 18 with a number
Working example at https://3v4l.org/iKskO

Adding a dynacmic data value in every particular data

hello new php programmer here, im creating an cms evaluation and i want the value of that evaluation to auto add and divided to a portion percentage ex.(35%) for that evaluation please kindly guide me how the logic.
Add all points with the eva 1 id compute the percentage base on given percent data
currently out put
code :
<?php echo $roweva["evaluation"];?>(<?php echo $roweva["percent"];?>%)
<?php echo $rowpts["points"]; ?> hidden-><?php echo $roweva["maxpts"]; ?>
view :
eva 1 (50%)
5
5
5
eva 2 (50%)
10
10
what i want to get for the output is the addition of all points of that particular evaluation and its percent %, for clear explanation see the example input and ouput below.
ex .
input / get data:
eval 1 50% --> 50%(if all q are max points)
ques1 5/10 -->/10(the maxpoints)
ques2 5/5 --> 3 ques
ques3 5/5
eval 2 50%
ques1 10/10 --> 2 ques
ques2 10/10
out put :
eval 1 = 15 points 37.5% ---(20 max pts & 75% of 50%)
eval 2 = 20 points 50% ---(20 max pts & 100% of 50%)

How to divide items equally in 4 boxes? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Suppose i have 7 bags with different weight. Actually a php array contains this data.
Bag A 60 Kg
Bag B 80 Kg
Bag C 20 Kg
Bag D 10 Kg
Bag E 80 Kg
Bag F 100 Kg
Bag G 90 Kg
In php it will look like this
Array
(
[30] => 60
[31] => 120
[32] => 120
[33] => 60
[35] => 180
)
Now i have to divide all 7 bags in 4 container equally by balancing there weight.
But i cannot break the bag to manage weight. How to do this please suggest me. How can i build a formula or php function which will distribute all bags balancing there weight.
There is no limitation in container capacity. And its also not necessary to have all containers weight equal after distribution. I just need a load balancing.
Thanks in advance.
Calculate the sum of the weight of your bags then divide it by the number of containers. Then use a bin packaging algorithm to distribute the bags to the individual containers. E.g. take one bag at a time from your array and put it in the first container where the weight of the container plus the weight of your bag is less than the maximally possible container weight.
http://en.wikipedia.org/wiki/Bin_packing_problem
Update:
example written in Ruby. Should be not to hard to rewrite it in PHP. It distributes the bags to the containers relatively evenly (There might be a solution that is more accurate).
# A list of bags with different weights
list_of_bags = [11, 41, 31, 15, 15, 66, 67, 34, 20, 42, 22, 25]
# total weight of all bags
weight_of_bags = list_of_bags.inject(0) {|sum, i| sum + i}
# how many containers do we have at our disposal?
number_of_containers = 4
# How much should one container weight?
weight_per_container = weight_of_bags / number_of_containers
# We make an array containing an empty array for each container
containers = Array.new(number_of_containers){ |i| [] }
# For each bag
list_of_bags.each do |bag|
# we try to find the first container
containers.each do |container|
# where the weight of the container plus the weigth of the bag is
# less than the maximum allowed (weight_per_container)
if container.inject(0) {|sum, i| sum + i} + bag < weight_per_container
# if the current container has space for it we add the bag
# and go to the next one
container.push(bag)
break
end
end
end
# output all containers with the number of items and total weight
containers.each_with_index do |container, index|
puts "container #{index} has #{container.length} items and weigths: #{container.inject(0) {|sum, i| sum + i}}"
end
example result:
container 0 has 3 items and weigths: 83
container 1 has 3 items and weigths: 96
container 2 has 2 items and weigths: 87
container 3 has 2 items and weigths: 76
Create a function that gets a product weight and returns a bag number - the one which has the least free space that's still enough to fit. Put it in the bag. Repeat until done.
$bags = array(60,80,20,10,80,100,90);
$containers = array(1=>100,2=>100,3=>100,4=>100); // number -> free space
$placement = array();
rsort($bags); // biggest first - usually it's better
function bestContainerFor($weight) {
global $containers;
$rest = 0;
$out = 0; // in it won't change $weight fits nowhere
foreach($containers as $nr=>$space) {
if($space<$weight) continue; // not enough space
if($space-$weight<$rest) continue; // we have a better case
$rest = $space-$weight;
$out = $nr;
}
if($out) $containers[$out]-=$weight; // occupy the space
return $out;
}
foreach($bags as $nr=>$w) {
$p = bestContainerFor($w);
$placement[$nr] = $p; // for later use; in this example it's not needed
if( $p) print "Bag $nr fits in $p<br>";
if(!$p) print "Bag $nr fits nowhere<br>";
}
It's not tested. If you give me some details of your code I'll try to adapt. This just shows the principle of it.
Note that
it works with variable container sizes,
it gives you the placement of each bag, not the sum weight,
it's not optimal for equal distribution, just gives a good case

Using PHP, how can I make a counter that turns any Int into 1 to 9999?

I have an internal counter that counts from 0-999999999999.
I would like this to display as a number between 0-9999, then rollover again.
This means:
0 displays as 1
1 displays as 2
9998 displays as 9999
...
9999 displays as 1
10000 displays as 2
...
19999 displays as 1
20000 displays as 2
edit:
1 + $number % 9999 was the answer (Thanks #Brad Christie). My table of expected results is wrong. (Thanks #Tevo D)
$x = 9280293;
$baseNineNineNineNine = $x % 9999;
Use MOD, it will give you the remainder past 9999 (e.g. Any number divided by 9999 can go in N times, with a remainder of Y (you'll end up with Y as a value)
For the numbers you're looking for, you may want to +1 any value you get after the MOD (%), or use 10000
See also the Modulus Operator
Take reminder with 10000, that guarantees the result to be in between 0 and 9999 and rolls over
$result = $int % 10000;
Your table of values doesn't match what you asking for. In the example you are using 9999 result values (1-9999) for 10000 input values. In the text you are saying 10000 output values (0-9999).
Here is what I think you are really asking for. This algorithm will output 1-9999 and then roll over to 1 again.
In other words, this solution will provide a four digit non-zero value:
$result = $int % 9999 + 1;
The output will NOT match your example, as your example has it rolling over every 10000 values, not 9999. Here is the output:
input output
0 1
1 2
.... ....
9997 9998
9998 9999
9999 1 <--- 9999 * 1
10000 2
.... ....
19996 9998
19997 9999
19998 1 <--- 9999 * 2
19999 2
.... ....
19995 9998
19996 9999
19997 1 <--- 9999 * 3
19998 2
.... ....

Finding factor for position

I know question title seems quite 'un-understandable', but I don't know how to write question title for this particular question.
Question:
I want to find factor for position.
Let me clear you with an example.
Value Factor
[Available] [Have to find out]
----------------------------------
1 10
3 10
9 10
10 10
11 10
25 10
50 10
75 10
99 10
100 100
101 100
105 100
111 100
127 100
389 100
692 100
905 100
999 100
1000 1000
1099 1000
1111 1000
4500 1000
6825 1000
7789 1000
9999 1000
10000 10000
10099 10000
51234 10000
98524 10000
99999 10000
100000 100000
and so on.
I hope you understand what I mean to get.
Assuming that the first three values should be 1 (as noted by Asaph), then you just need to use all that logarithm stuff you learned in school:
pow(10, floor(log10($n)))
So, how does this work? The base-10 logarithm of a number x is the y such that 10^y = x (where ^ stands for exponentiation). This gives us the following:
log( 1) 0
log( 10) 1
log(100) 2
...
So the log10 of a number between 1 and 10 will be between 0 and 1, the log10 of a number between 10 and 100 will be between 1 and 2, etc. The floor function will give you the integer part of the logarithm (we're only dealing with non-negative values here so there's no need to worry about which direction floor goes with negative values) so floor(log10()) will be 0 for for anything between 1 and 10, 1 for anything between 10 and 100, etc. Now we have how many factors of ten we need so a simple pow(10, ...) gives us the final result.
References:
log10
floor
pow
I'm still a little unsure of what you're asking, but it seems like you want to map values to other values... In php arrays can be indexed with anything (making them a map). If 999 always means a factor of 100 and 1099 always means a factor of 1000, you can set the value of array[999] to 100 and the value of array[1099] to 1000, etc.
Basically Factor is 10 to the power of number of digits in $value minus 1 (except for the single digit numbers):
if($value < 10) {
$value += 10;
}
$numOfDigits = count(str_split($value,1));
$factor = pow(10,$numDigits-1);
This function should work for you. It seems like the first 3 "factors" in your list don't fit the pattern. If, in your sample data set, those first 3 "factors" should really be 1 instead of 10, then you can safely remove the first 3 lines of the body of the function below.
function getFactor($num) {
if ($num < 10) { // If the first 3 "factors" listed
return 10; // in the question should be 1 instead of 10
} // then remove these 3 lines.
$factor = 1;
while($factor <= $num) {
$factor *= 10;
}
return $factor / 10;
}

Categories