Replace string within parenthesis with column data - php

I have written some code to allow calculations to be done on specific columns of data.
For example {1}*{2} would result in column 1 being multiplied by column 2. What I need to be able to do is replace these numbers with the actual values of the column.
Putting it simply I need to be able to get the value within the parenthesis, then use it like $column["value from parenthesis"] to get the value to insert into the calculation.
I can then evaluate the string.
Thanks in advance

Something like this should work:
$myString = '{1}*{2}';
$myValues = [1 => '684', 2 => '42'];
$myFormula = preg_replace_callback('{([0-9]+)}', function($match) use ($myValues) {
return $myValues[$match] ?: 'undefined';
}, $myString);
echo "Resulting formula: $myFormula";
Might want to give a harder error when an undefined index is used, but essentially this should work with some tweaking.
Also if you run a older PHP version than 5.4 you would need to rewrite the short array syntax and the lambda.

PHP Rocks !!!
$string = 'blabla bla I want this to be done !!! {10} + {12} Ah the result is awesome but let\'s try something else {32} * {54}';
// Requires PHP 5.3+
$string = preg_replace_callback('/\{(\d+(\.\d+)?)\}\s*([\+\*\/-])\s*\{(\d+(\.\d+)?)\}/', function($m){
return mathOp($m[3], $m[1], $m[4]);
}, $string);
echo $string; // blabla bla I want this to be done !!! 22 Ah the result is awesome but let's try something else 1728
// function from: http://stackoverflow.com/a/15434232
function mathOp($operator, $n1, $n2){
if(!is_numeric($n1) || !is_numeric($n2)){
return 'Error: You must use numbers';
}
switch($operator){
case '+':
return($n1 + $n2);
case '-':
return($n1 - $n2);
case '*':
return($n1 * $n2);
case '/':
if($n2 == 0){
return 'Error: Division by zero';
}else{
return($n1 / $n2);
}
default:
return 'Unknown Operator detected';
}
}
Online demo.

Related

PHP Query - Check string character

if (substr('xcazasd123', 0, 2) === 'ax'){
}
Above code is working where it able to check if the "variable" is
starting with 'ax', but what if i wanted to check "multiple"
different validation ?
for example : 'ax','ab','ac' ? Without creating multiple if statement
You can use array to store your keywords and then use in_array() if you want to avoid multiple if statements.
$key_words =["ax","ab","ac"]
if (in_array( substr('yourstringvalue', 0, 2), $key_words ){
//your code
}
References:
in_array — Checks if a value exists in an array
If this sub-string is always in the same place - easy and fast is switch
// $x = string to pass
switch(substr($x,0,2)){
case 'ax': /* do ax */ break;
case 'ab': /* do ab */ break;
case 'ac': /* do ac */ break; // break breaks execution
case 'zy': /* do ZY */ // without a break this and next line will be executed
case 'zz': /* do ZZ */ break; // for zz only ZZ will be executed
default: /* default proceed */}
switch pass exact values in case - any other situation are not possible or weird and redundant.
switch can also evaluate through default to another one switch or other conditions
manual
You can use preg_match approach for test the string:
if(preg_match('/^(ax|ab|ac)/', '1abcd_test', $matches)) {
echo "String starts with: " . $matches[1];
} else {
echo "String is not match";
}
Example: PHPize.online
You can learn about PHP Regular Expressions fro more complicated string matching

How can I change my code, so that it also solves math string expressions?

I want the following code below, that it also solves math string expressions (/, +, -, and *).
array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));
As it is right now, the code above ignores the math problems and sticks to the sum instead. For an example:
expenses|test-1|628
expenses|test-2|2348/2
expenses|test-3|379
With the code of arrays above, the sum will be 3355. The correct sum is 2181.
To fully understand the current code line please see this answer of my last question.
This should work for you:
Just add this function to your code:
function calculateBasicMath($expression) {
$expression = preg_replace("/[^0-9\+\-\*\/\.\,]/", "", $expression);
while(preg_match("/(\d+)([\*\/])(\d+)/", $expression, $hM) || preg_match("/(\d+)([\+\-])(\d+)/", $expression, $lM)) {
if(!empty($hM)) {
switch($hM[2]){
case "*":
$expression = str_replace("$hM[1]$hM[2]$hM[3]", $hM[1] * $hM[3], $expression);
break;
case "/":
$expression = str_replace("$hM[1]$hM[2]$hM[3]", $hM[1] / $hM[3], $expression);
break;
}
} elseif(!empty($lM)) {
switch($lM[2]){
case "+":
$expression = str_replace("$lM[1]$lM[2]$lM[3]", $lM[1] + $lM[3], $expression);
break;
case "-":
$expression = str_replace("$lM[1]$lM[2]$lM[3]", $lM[1] - $lM[3], $expression);
break;
}
} else {
break;
}
}
return $expression;
}
And then change your line from:
array_sum(array_column(array_intersect_key($lines, array_flip($keys)), 2));
to:
array_sum(array_map("calculateBasicMath", array_column(array_intersect_key($lines, array_flip($keys)), 2)));
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ See here
So that it basically calls this function for each value.
The function itself first replaces everything expect: [0-9]+-/*., with preg_replace(). Then it simply searches for basic math, e.g. X[+-*/]X. But where / and * has a higher precedence than + and -. And as long as it finds such a math expressions it calculates these and replace them.

check that the value of a variable is in a particular range of values

First of all I want to say I am not a programmer but I have been playing around with some simple php scripts today and I have a quick question for those in the know. How could I simplify the following code so it does not use all of those OR logical operators?
$number = "";
if ("$number" == 2 || "$number" == 3 || "$number" == 8 || "$number" == 10)
{
echo ('Your number is ' . "$number");
}
Thanks,
Kris
<?php
if (in_array($number,array(2,3,8,10))) {
echo 'Your number is '.$number;
}
or
<?php
switch ($number) {
case 2:
case 3:
case 8:
case 10:
echo 'Your number is '.$number;
break;
case 99;
echo 'Your number is 99';
break;
}
Firstly, although quotations around your variables don't cause the code to break, you really really don't need them and in fact the only reason your code still works is because PHP has a strange system to match between strings and integers.
Anyway, one way to rewrite that code is as
$validNumbers = array(2,3,8,10);
if (in_array($number, $validNumbers))
{
echo ('Your number is '. $number);
}
Technically, you could also do
if ((1 << $number) & 1292)
if you're into unreadable code. This works because the binary representation of 1292 has a 1 exactly at the binary digits 2, 3, 8, and 10.
You can't make it simpler in a way that makes sense. I would keep it just like that.
EDIT: By "simplification" I would guess that you want to do less operations...
you could do this:
$valid_numbers = array(2, 3, 8, 10);
if (in_array($number, $valid_numbers)) {
echo 'Your number is ', $number;
}
p.s.: you don't need/it's wrong to put $number between quotes, since you're expecting an int.
hope this helps

How to convert some character into numeric in php?

I need help to change a character in php.
I got some code from the web:
char dest='a';
int conv=(int)dest;
Can I use this code to convert a character into numeric? Or do you have any ideas?
I just want to show the result as a decimal number:
if null == 0
if A == 1
Use ord() to return the ascii value. Subtract 96 to return a number where a=1, b=2....
Upper and lower case letters have different ASCII values, so if you want to handle them the same, you can use strtolower() to convert upper case to lower case.
To handle the NULL case, simply use if($dest). This will be true if $dest is something other than NULL or 0.
PHP is a loosely typed language, so there is no need to declare the types. So char dest='a'; is incorrect. Variables have $ prefix in PHP and no type declaration, so it should be $dest = 'a';.
Live Example
<?php
function toNumber($dest)
{
if ($dest)
return ord(strtolower($dest)) - 96;
else
return 0;
}
// Let's test the function...
echo toNumber(NULL) . " ";
echo toNumber('a') . " ";
echo toNumber('B') . " ";
echo toNumber('c');
// Output is:
// 0 1 2 3
?>
PS:
You can look at the ASCII values here.
It does indeed work as in the sample, except that you should be using php syntax (and as a sidenote: the language that code you found most probably was, it did not do the same thing).
So:
$in = "123";
$out = (int)$in;
Afterwards the following will be true:
$out === 123
This may help you:
http://www.php.net/manual/en/function.ord.php
So, if you need the ASCII code you will need to do:
$dest = 'a';
$conv = ord($dest);
If you want something like:
a == 1
b == 2
.
.
.
you should do:
$dest = 'a';
$conv = ord($dest)-96;
For more info on the ASCII codes: http://www.asciitable.com/
And for the function ord: http://www.php.net/manual/en/function.ord.php
It's very hard to answer because it's not a real question but just a little bit of it.
But if you ask.
It seems you need some translation table, that defines links between letters and numbers
A -> 2
B -> 3
C -> 4
S -> 1
or whatever.
You can achieve this by using an array, where keys would be these letters and values - desired numbers.
$defects_arr = array(
'A' -> 2,
'B' -> 3,
'C' -> 4'
'S' -> 1
};
Thus, you can convert these letters to numbers
$letter = 'A';
$number = $defects_arr($letter);
echo $number; // outputs 1
But it still seems is not what you want.
Do these defect types have any verbose equivalents? If so, why not to use them instead of letters?
Telling the whole story instead of little bit of it will help you to avoid mistakes and will save a ton of time, both yours and those who to answer.
Out of this question, if you are looking for convert RT0005 to 5
$max = 'RT0005';
return base_convert($max,10,10);
// return 5

simplest, shortest way to count capital letters in a string with php?

I am looking for the shortest, simplest and most elegant way to count the number of capital letters in a given string.
function count_capitals($s) {
return mb_strlen(preg_replace('![^A-Z]+!', '', $s));
}
$str = "AbCdE";
preg_match_all("/[A-Z]/", $str); // 3
George Garchagudashvili Solution is amazing, but it fails if the lower case letters contain diacritics or accents.
So I did a small fix to improve his version, that works also with lower case accentuated letters:
public static function countCapitalLetters($string){
$lowerCase = mb_strtolower($string);
return strlen($lowerCase) - similar_text($string, $lowerCase);
}
You can find this method and lots of other string common operations at the turbocommons library:
https://github.com/edertone/TurboCommons/blob/70a9de1737d8c10e0f6db04f5eab0f9c4cbd454f/TurboCommons-Php/src/main/php/utils/StringUtils.php#L373
EDIT 2019
The method to count capital letters in turbocommons has evolved to a method that can count upper case and lower case characters on any string. You can check it here:
https://github.com/edertone/TurboCommons/blob/1e230446593b13a272b1d6a2903741598bb11bf2/TurboCommons-Php/src/main/php/utils/StringUtils.php#L391
Read more info here:
https://turbocommons.org/en/blog/2019-10-15/count-capital-letters-in-string-javascript-typescript-php
And it can also be tested online here:
https://turbocommons.org/en/app/stringutils/count-capital-letters
I'd give another solution, maybe not elegant, but helpful:
$mixed_case = "HelLo wOrlD";
$lower_case = strtolower($mixed_case);
$similar = similar_text($mixed_case, $lower_case);
echo strlen($mixed_case) - $similar; // 4
It's not the shortest, but it is arguably the simplest as a regex doesn't have to be executed. Normally I'd say this should be faster as the logic and checks are simple, but PHP always surprises me with how fast and slow some things are when compared to others.
function capital_letters($s) {
$u = 0;
$d = 0;
$n = strlen($s);
for ($x=0; $x<$n; $x++) {
$d = ord($s[$x]);
if ($d > 64 && $d < 91) {
$u++;
}
}
return $u;
}
echo 'caps: ' . capital_letters('HelLo2') . "\n";

Categories