Conditional in find and replace php function - php

I have this function which searches for strings like this:
<unique>342342342</unique>
<unique>5345345345345435345</unique>
<unique>4444</unique>
function:
$pattern = '/<unique>(.*?)<\/unique>/';
$response = preg_replace_callback($pattern,function($match){
$value = intval(trim($match[1])/200);
return '<unique>'.$value.'</unique>';
},$xml);
and change the number to its half (n/2). So far so good.
But I need to add a conditional to check if the number has more than 10 digits, if true then makes the change, if not, doesn't.
I tried this, but nope...all instances de '4444' get removed
$pattern = '/<unique>(.*?)<\/unique>/';
$response = preg_replace_callback($pattern,function($match){
$valueunique = trim($match[1]);
if(strlen($valueunique) >= 11){
$value = intval($valueunique/200);
return '<unique>'.$value.'</unique>';
}
},$xml);

Just move the return outside the if block:
$xml = '<unique>342342342</unique>
<unique>5345345345345435345</unique>
<unique>4444</unique>';
$pattern = '/<unique>(.*?)<\/unique>/';
$response = preg_replace_callback($pattern,function($match){
$value = trim($match[1]);
if(strlen($value) >= 11){
$value = intval($value/200);
}
return '<unique>'.$value.'</unique>';
},$xml);
echo "response = $response\n";
Output:
response = <unique>342342342</unique>
<unique>26726726726727180</unique>
<unique>4444</unique>

Related

PHP url array search and return closest url

I have the following array with urls
$data = Array ( 'http://localhost/my_system/users',
'http://localhost/my_system/users/add_user',
'http://localhost/my_system/users/groups',
'http://localhost/my_system/users/add_group' );
Then I have a variable
$url = 'http://localhost/my_system/users/by_letter/s';
I need a function that will return the closest url from the array if $url does not exist. Something like
function get_closest_url($url,$data){
}
get_closest_url($url,$data); //returns 'http://localhost/my_system/users/'
$url2 = 'http://localhost/my_system/users/groups/ungrouped';
get_closest_url($url2,$data); //returns 'http://localhost/my_system/users/groups/'
$url3 = 'http://localhost/my_system/users/groups/add_group/x/y/z';
get_closest_url($url3,$data); //returns 'http://localhost/my_system/users/groups/add_group/'
You can explode both the current URL and each of the URLs in $data, intersect the arrays, then return the array with the most elements (best match). If there's no matches, return false:
<?php
$data = [ "localhost/my_system/users",
"localhost/my_system/users/add_user",
"localhost/my_system/users/by_letter/groups",
"localhost/my_system/users/add_group"];
$url = "localhost/my_system/users/by_letter/s";
function getClosestURL($url, $data) {
$matches = [];
$explodedURL = explode("/", $url);
foreach ($data as $match) {
$explodedMatch = explode("/", $match);
$matches[] = array_intersect($explodedMatch, $explodedURL);
}
$bestMatch = max($matches);
return count($bestMatch) > 0 ? implode("/", $bestMatch) : false; // only return the path if there are matches, otherwise false
}
var_dump(getClosestURL($url, $data)); //returns localhost/my_system/users/by_letter
var_dump(getClosestURL("local/no/match", $data)); //returns false
Demo
You don't mention how you want to specifically check if the URL exists. If it needs to be "live", you can use get_headers() and check the first item for the HTTP status. If it's not 200, you can then go ahead with the URL intersection.
$headers = get_headers($url);
$httpStatus = substr($headers[0], 9, 3);
if ($httpStatus === "200") {
return $url; // $url is OK
}
// else, keep going with the previous function
function get_closest_url($item,$possibilities){
$result = [];
foreach($possibilities as $possibility){
$lev = levenshtein($possibility, $item);
if($lev === 0){
#### we have got an exact match
return $possibility;
}
#### if two possibilities have the same lev we return only one
$result[$lev] = $possibility;
}
#### return the highest
return $result[min(array_keys($result))];
}
That should do it.

How to add string to a PHP variable?

I'm not sure it's even the right way to define this question.
I have string that may be exist, and may not. It happens to be a number: $number
If $number doesn't exist, then I want to use the PHP variable $url.
But if $number does exist, then I want to use the PHP variable which is named $url+the number, i.e, $url2 if $number=2
So I tried this code, but it doesn't work:
$number = "2"; //(Can be either missing, or equal to 1, 2, or 3)
$url = "www.0.com"; // Fallback
$url1 = "www.1.com";
$url2 = "www.2.com";
$url3 = "www.3.com";
$result = $url.=$number ;
// If $number=1, I want $result to be : www.1.com
// If $number=2, I want $result to be : www.2.com
// If $number=3, I want $result to be : www.3.com
// If $number IS NOT SET, I want $result to be : www.0.com
// Now do something with $result
Perhaps there's a completely better way to achieve what I want (will be happy to see example), but anyway I'm curious as well to understand how to achieve it my way.
Okay, so you're talking about a variable variable.
You should define the name of the variable you need to use in a string, and then pass that to a variable variable using $$ syntax:
if( isset($number) && is_numeric($number) )
{
$name = 'url'.$number;
$result = $$name;
}
else
{
$result = $url;
}
That having been said, you may be better off using an array for this:
$urls = [ 'www.0.com', 'www.1.com', 'www.2.com', 'www.3.com' ];
$result = (!isset($number)) ? $urls[0] : $urls[ intval($number) ];
You can use ternary with in_array and empty.
$number = "2"; //(Can be either missing, or equal to 1, 2, or 3)
$url = "www.0.com"; // Fallback
$url1 = "www.1.com";
$url2 = "www.2.com";
$url3 = "www.3.com";
$result = (!empty($number) && in_array($number, array(1,2,3))) ? ${'url' . $number} : $url;
echo $result;
Demo: https://eval.in/821737
In php you can have things like dynamic variable names:
$variableName = "url".$number;
$result = $$variableName;
However, you should make sure, that $variableName refers to an existing variable:
$result = "www.fallbackURL.com";
if(isset($$variableName)) $result = $$variableName;
Or Try this code:
$number = 5;
$url[0] = "www.0.com"; // Fallback
$url[1] = "www.1.com";
$url[2] = "www.2.com";
$url[3] = "www.3.com";
if (!isset($number)) $number=0;
if (!isset($url[$number])) $number=0;
$result = $url[$number];
If you add $ front of string, it define variable, so you can use following code:
<?php
$number = "2"; //(Can be either missing, or equal to 1/2/3)
$url = "www.0.com"; // Fallback
$url1 = "www.1.com";
$url2 = "www.2.com";
$url3 = "www.3.com";
if(isset($number) && is_numeric($number) && $number <= 3) {
$variable_name = 'url' . $number; //string like url2
} else {
$variable_name = 'url';
}
$result = $$variable_name ; //define $url2 from url2 string
echo $result;
// Now do something with $result
Example for define variable with string variable:
$string = 'hello';
$$string = 'new variable'; //define $hello variable
echo $hello; //Output: "new variable"
if the url need just a number, you can do this easy way
($number)?$number:0;
$url = "www.".$number.".com";
if there are specific real url, you can use array
$array[0] = "www.google.com";
$array[1] = "www.facebook.com";
($number)?$number:0;
url = $array[$number];
Updated code:
$number = "2";
if(isset($number)){
$res = "url".$number;
$result=$$res;
}else{
$result=$url;
}
echo $result;

php strpos and approximate match with 1 character difference

I searched the system but couldn't find any help I could understand on this, so here goes...
I need to find an approximate match for a string in php.
Essentially I'm checking that all the $names are in the $cv string and if not it sets a flag to true.
foreach( $names as $name ) {
if ( strrpos( $cv, $name ) === false ) {
$nonameincv = true;
}
}
It works fine. However, I had a case of $cv = "marie_claire" and a $name = "clare" which set the flag (of course) but which I'd have liked for strpos to have "found" as it were.
Is it possible to do an approximate match so that if a string has 1 extra letter anywhere in it, it would match? For example so that:
$name = "clare" is found in $cv = "marie_claire"
$name = "caire" is found in $cv = "marie_claire"
$name = "laire" is found in $cv = "marie_claire"
and so on...
Note: This will work perfectly fine when there is difference of 1 character, as stated in question above.
Try this code snippet here
<?php
ini_set('display_errors', 1);
$stringToSearch="mare";
$wholeString = "marie_claire";
$wholeStringArray= str_split($wholeString);
for($x=0;$x<strlen($wholeString);$x++)
{
$tempArray=$wholeStringArray;
unset($tempArray[$x]);
if(strpos(implode("", $tempArray), $stringToSearch)!==false)
{
echo "Found: $stringToSearch in ".implode("", $wholeStringArray);
break;
}
}
Try this, not considering performance, but would work for your case.You can play with the the number of different chars deviation you want to accept.
$names = array("clare", "caire", "laire");
$cv = "marie_claire";
foreach( $names as $name ) {
$sname = str_split($name);
$words = explode('_', $cv);
foreach($words as $word) {
$sword = str_split($word);
$result = array_diff($sword, $sname);
if(count($result) < 2)
echo $name. ":true\r\n";
}
}

Change portion of value within an array knowing only part of string and restric

Before I got this answer
preg_replace("~(?<=$str&&).*~", '7', $str);
which is good but what if within the array I have a similar string mary&&5 and rosemary&&5 and I stricktly want to change only mary&&5 and not disturb the other array, is it posible? and how?
The question before was:
`$array = array("josh&&3", "mary&&5", "cape&&4", "doggy&&8", etc..);`
and I know only the string before && which is username. $str = "mary&&"; Note that I don't know what is after &&
I want to know whether exist or not within the array, and if exist change the value to something new like mary&&7
`$isExists = preg_replace("some","some", $array);
if ($isExists){
echo "Its exists";
} else {
echo "Not exixts"
} ;`
How can I change the portion of the value after && in mary&&5 or completely change mary&&5 to mary&&7 since I don't know before hand the value mary&&5?
Thanks for your answer :)
`$name = "mary";
$res = "7";
$str = array("josh&&3", "mary&&5", "cape&&4", "doggy&&8","rosemary&&5");
for ($i = 0; $i < count($str); ++$i) {
$r = preg_replace("~(?<=$name).*~",$res, $str);}`
$arr = array('josh&&3', 'mary&&5', 'cape&&4', 'doggy&&8', 'rosemary&&5');
$name = 'mary';
$number = '7';
$replacement = $name . '&&' . $number;
So, a way without regex:
foreach($arr as $k=>$v) {
if (explode('&&', $v)[0] === $name)
$arr[$k] = $replacement;
}
( or you can use strpos($v, $name . '&&') === 0 as condition)
a way with regex:
$arr = preg_filter('~\A' . $name . '&&\K.*~', $number, $arr);
(where \K removes all on the left from the match result, so the name and && aren't replaced)

Convert a String to Variable

I've got a multidimensional associative array which includes an elements like
$data["status"]
$data["response"]["url"]
$data["entry"]["0"]["text"]
I've got a strings like:
$string = 'data["status"]';
$string = 'data["response"]["url"]';
$string = 'data["entry"]["0"]["text"]';
How can I convert the strings into a variable to access the proper array element? This method will need to work across any array at any of the dimensions.
PHP's variable variables will help you out here. You can use them by prefixing the variable with another dollar sign:
$foo = "Hello, world!";
$bar = "foo";
echo $$bar; // outputs "Hello, world!"
Quick and dirty:
echo eval('return $'. $string . ';');
Of course the input string would need to be be sanitized first.
If you don't like quick and dirty... then this will work too and it doesn't require eval which makes even me cringe.
It does, however, make assumptions about the string format:
<?php
$data['response'] = array(
'url' => 'http://www.testing.com'
);
function extract_data($string) {
global $data;
$found_matches = preg_match_all('/\[\"([a-z]+)\"\]/', $string, $matches);
if (!$found_matches) {
return null;
}
$current_data = $data;
foreach ($matches[1] as $name) {
if (key_exists($name, $current_data)) {
$current_data = $current_data[$name];
} else {
return null;
}
}
return $current_data;
}
echo extract_data('data["response"]["url"]');
?>
This can be done in a much simpler way. All you have to do is think about what function PHP provides that creates variables.
$string = 'myvariable';
extract(array($string => $string));
echo $myvariable;
done!
You can also use curly braces (complex variable notation) to do some tricks:
$h = 'Happy';
$n = 'New';
$y = 'Year';
$wish = ${$h.$n.$y};
echo $wish;
Found this on the Variable variables page:
function VariableArray($data, $string) {
preg_match_all('/\[([^\]]*)\]/', $string, $arr_matches, PREG_PATTERN_ORDER);
$return = $arr;
foreach($arr_matches[1] as $dimension) { $return = $return[$dimension]; }
return $return;
}
I was struggling with that as well,
I had this :
$user = array('a'=>'alber', 'b'=>'brad'...);
$array_name = 'user';
and I was wondering how to get into albert.
at first I tried
$value_for_a = $$array_name['a']; // this dosen't work
then
eval('return $'.$array_name['a'].';'); // this dosen't work, maybe the hoster block eval which is very common
then finally I tried the stupid thing:
$array_temp=$$array_name;
$value_for_a = $array_temp['a'];
and this just worked Perfect!
wisdom, do it simple do it stupid.
I hope this answers your question
You would access them like:
print $$string;
You can pass by reference with the operator &. So in your example you'll have something like this
$string = &$data["status"];
$string = &$data["response"]["url"];
$string = &$data["entry"]["0"]["text"];
Otherwise you need to do something like this:
$titular = array();
for ($r = 1; $r < $rooms + 1; $r ++)
{
$title = "titular_title_$r";
$firstName = "titular_firstName_$r";
$lastName = "titular_lastName_$r";
$phone = "titular_phone_$r";
$email = "titular_email_$r";
$bedType = "bedType_$r";
$smoker = "smoker_$r";
$titular[] = array(
"title" => $$title,
"first_name" => $$firstName,
"last_name" => $$lastName,
"phone" => $$phone,
"email" => $$email,
"bedType" => $$bedType,
"smoker" => $$smoker
);
}
There are native PHP function for this:
use http://php.net/manual/ru/function.parse-str.php (parse_str()).
don't forget to clean up the string from '"' before parsing.
Perhaps this option is also suitable:
$data["entry"]["0"]["text"];
$string = 'data["entry"]["0"]["text"]';
function getIn($arr, $params)
{
if(!is_array($arr)) {
return null;
}
if (array_key_exists($params[0], $arr) && count($params) > 1) {
$bf = $params[0];
array_shift($params);
return getIn($arr[$bf], $params);
} elseif (array_key_exists($params[0], $arr) && count($params) == 1) {
return $arr[$params[0]];
} else {
return null;
}
}
preg_match_all('/(?:(\w{1,}|\d))/', $string, $arr_matches, PREG_PATTERN_ORDER);
array_shift($arr_matches[0]);
print_r(getIn($data, $arr_matches[0]));
P.s. it's work for me.

Categories