Unable to echo the real value of a variable - php

Iam given the following variable: %4$s that outputs the text "a test" in the code.
I am trying to echo strlen('%4$s'); but it always returns 4 , while adding it as echo strlen("%4$s"); is not returning again the real value (2), which in my opinion means that for some reason, is uses the number of the variable.
My primary scope is to check if %4$s contains two or more words or to count the characters of a returned string.
At this time, %4$s , returns 'a test' in my HTML, so I m expecting an echo of %4$s to return 'a test' in PHP and a strlen of %4$s to return number 6

It looks like you are using a string format suitable for something like printf() or sprintf() and you are wanting to know the length of the 4th entered value.
Sample code:
$format = '%4$s';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4);
Which will display:
a test
And you want to know the length of that 4th value. Instead of strlen('%4$s'), you should be doing strlen($val4), for example:
echo strlen($val4);
Which will show:
6
A full example would be:
$format = '%5$d is the strlen of "%4$s"';
$val1 = 'one';
$val2 = 'two';
$val3 = 'three';
$val4 = 'a test';
echo sprintf($format,$val1,$val2,$val3,$val4,strlen($val4));
Which will display:
6 is the strlen of "a test"
Edit: It is still not very clear what you are doing even after looking at the pastebin link you posted. That said, the following is a guess that works. It uses the vsprintf() method:
$format = '%6$s is the strlen of "%4$s"';
$retArr[0] = array('post_id' => 'one',
'icon' => 'two',
'title' => 'three',
'permalink' => 'a test',
'image' => '/path/to/img.png');
$retArr[0]['len'] = strlen($retArr[0]['permalink']);
echo vsprintf($format,$retArr[0]);
And still outputs:
6 is the strlen of "a test"

Referring : http://php.net/manual/en/language.types.string.php
Note: Unlike the double-quoted and heredoc syntaxes, variables and escape sequences for special characters will not be expanded when they occur in single quoted strings.
Double quoted ¶
If the string is enclosed in double-quotes ("), PHP will interpret the following escape sequences for special characters:
$
is an escape character in php and if you don't escape it correctly using "\" like "\$s" "s" will be treated as a variable "$s".
Hence you are getting count as 2

strlen returns the amount of letters in a string so that's why you are getting the number 4 instead of your string.
try : '%4'.$s

Here's an answer that will count string length (by char) and do a word count.
Note: This isn't a copy-and-paste solution, so you will need to change your code to fit.
You can get the word count easily by doing the generic rule that words are separated by spaces. Here's where a PHP function called explode() comes in. We can use that combined with count() to get the word count:
$foo = 'a test';
$wordCount = count(explode(' ', $foo));
$strLength = strlen($foo);
echo $wordCount; # will output 2
echo $strLength; # will output 6
I've seen your pastebin for your array data, you can just loop through the array to get the individual values or use $array[$key] to specify a certain value to target.

Related

Function with custom pattern output [duplicate]

I'm having a hard time understanding when strtr would be preferable to str_replace or vice versa. It seems that it's possible to achieve the exact same results using either function, although the order in which substrings are replaced is reversed. For example:
echo strtr('test string', 'st', 'XY')."\n";
echo strtr('test string', array( 's' => 'X', 't' => 'Y', 'st' => 'Z' ))."\n";
echo str_replace(array('s', 't', 'st'), array('X', 'Y', 'Z'), 'test string')."\n";
echo str_replace(array('st', 't', 's'), array('Z', 'Y', 'X'), 'test string');
This outputs
YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring
Aside from syntax, is there any benefit to using one over the other? Any cases where one would not be sufficient to achieve a desired result?
First difference:
An interesting example of a different behaviour between strtr and str_replace is in the comments section of the PHP Manual:
<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
I would expect as result: "ZDDB"
However, this return: "ZDDD"
(Because B = D according to our array)
To make this work, use "strtr" instead:
<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
This returns: "ZDDB"
This means that str_replace is a more global approach to replacements, while strtr simply translates the chars one by one.
Another difference:
Given the following code (taken from PHP String Replacement Speed Comparison):
<?php
$text = "PHP: Hypertext Preprocessor";
$text_strtr = strtr($text
, array("PHP" => "PHP: Hypertext Preprocessor"
, "PHP: Hypertext Preprocessor" => "PHP"));
$text_str_replace = str_replace(array("PHP", "PHP: Hypertext Preprocessor")
, array("PHP: Hypertext Preprocessor", "PHP")
, $text);
var_dump($text_strtr);
var_dump($text_str_replace);
?>
The resulting lines of text will be:
string(3) "PHP"
string(27) "PHP: Hypertext Preprocessor"
The main explanation:
This happens because:
strtr: it sorts its parameters by length, in descending order, so:
it will give "more importance" to the largest one, and then, as the subject text is itself the largest key of the replacement array, it gets translated.
because all the chars of the subject text have been replaced, the process ends there.
str_replace: it works in the order the keys are defined, so:
it finds the key “PHP” in the subject text and replaces it with: “PHP: Hypertext Preprocessor”, what gives as result:
“PHP: Hypertext Preprocessor: Hypertext Preprocessor”.
then it finds the next key: “PHP: Hypertext Preprocessor” in the resulting text of the former step, so it gets replaced by "PHP", which gives as result:
“PHP: Hypertext Preprocessor”.
there are no more keys to look for, so the replacement ends there.
It seems that it's possible to achieve the exact same results using either function
That's not always true and depends on the search and replace data you provide. For example where the two function differ see: Does PHP str_replace have a greater than 13 character limit?
strtr will not replace in parts of the string that already have been replaced - str_replace will replace inside replaces.
strtr will start with the longest key first in case you call it with two parameters - str_replace will replace from left to right.
str_replace can return the number of replacements done - strtr does not offer such a count value.
I think strtr provides more flexible and conditional replacement when used with two arguments, for example: if string is 1, replace with a, but if string is 10, replace with b. This trick could only be achieved by strtr.
$string = "1.10.0001";
echo strtr($string, array("1" => "a", "10" => "b"));
// a.b.000a
see : Php Manual Strtr.
Notice in manual
STRTR--
Description
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
If given three arguments, this function returns a copy of str where ...
STR_REPLACE--
...
If search or replace are arrays, their elements are processed first to last.
...
STRTR each turn NOT effect to next, BUT STR_REPLACE does.

PHP convert double quoted string to single quoted string

I know this question asked here many times.But That solutions are not useful for me. I am facing this problem very badly today.
// Case 1
$str = 'Test \300'; // Single Quoted String
echo json_encode(utf8_encode($str)) // output: Test \\300
// Case 2
$str = "Test \300"; // Double Quoted String
echo json_encode(utf8_encode($str)) // output: Test \u00c0
I want case 2's output and I have single quoted $str variable. This variable is filled from XML string parsing . And that XML string is saved in txt file.
(Here \300 is encoding of À (latin Charactor) character and I can't control it.)
Please Don't give me solution for above static string
Thanks in advance
This'll do:
$string = '\300';
$string = preg_replace_callback('/\\\\\d{1,3}/', function (array $match) {
return pack('C', octdec($match[0]));
}, $string);
It matches any sequence of a backslash followed by up to three numbers and converts that number from an octal number to a binary string. Which has the same result as what "\300" does.
Note that this will not work exactly the same for escaped escapes; i.e. "\\300" will result in a literal \300 while the above code will convert it.
If you want all the possible rules of double quoted strings followed without reimplementing them by hand, your best bet is to simply eval("return \"$string\""), but that has a number of caveats too.
May You are looking for this
$str = 'Test \300'; // Single Quoted String
echo json_encode(stripslashes($str)); // output: Test \\300

Extract first integer in a string with PHP

Consider the following strings:
$strings = array(
"8.-10. stage",
"8. stage"
);
I would like to extract the first integer of each string, so it would return
8
8
I tried to filter out numbers with preg_replace but it returns all integers and I only want the first.
foreach($strings as $string)
{
echo preg_replace("/[^0-9]/", '',$string);
}
Any suggestions?
A convenient (although not record-breaking in performance) solution using regular expressions would be:
$string = "3rd time's a charm";
$filteredNumbers = array_filter(preg_split("/\D+/", $string));
$firstOccurence = reset($filteredNumbers);
echo $firstOccurence; // 3
Assuming that there is at least one number in the input, this is going to print the first one.
Non-digit characters will be completely ignored apart from the fact that they are considered to delimit numbers, which means that the first number can occur at any place inside the input (not necessarily at the beginning).
If you want to only consider a number that occurs at the beginning of the string, regex is not necessary:
echo substr($string, 0, strspn($string, "0123456789"));
preg_match('/\d+/',$id,$matches);
$id=$matches[0];
If the integer is always at the start of the string:
(int) $string;
If not, then strpbrk is useful for extracting the first non-negative number:
(int) strpbrk($string, "0123456789");
Alternatives
These one-liners are based on preg_split, preg_replace and preg_match:
preg_split("/\D+/", " $string")[1];
(int) preg_replace("/^\D+/", "", $string);
preg_match('/\d+/', "$string 0", $m)[0];
Two of these append extra character(s) to the string so empty strings or strings without numbers do not cause problems.
Note that these alternative solutions are for extracting non-negative integers only.
Try this:
$strings = array(
"8.-10. stage",
"8. stage"
);
$res = array();
foreach($strings as $key=>$string){
preg_match('/^(?P<number>\d)/',$string,$match);
$res[$key] = $match['number'];
}
echo "<pre>";
print_r($res);
foreach($strings as $string){
if(preg_match("/^(\d+?)/",$string,$res)) {
echo $res[1].PHP_EOL;
}
}
if you have Notice in PHP 7 +
Notice: Only variables should be passed by reference in YOUR_DIRECTORY_FILE.php on line LINE_NUMBER
By using this code
echo reset(array_filter(preg_split("/\D+/", $string)));
Change code to
$var = array_filter(preg_split("/\D+/", $string));
return reset($var);
And enjoy! Best Regards Ovasapov
How to filter out all characters except for the first occurring whole integer:
It is possible that the target integer is not at the start of the string (even if the OP's question only provides samples that start with an integer -- other researchers are likely to require more utility ...like the pages that I closed today using this page). It is also possible that the input contains no integers, or no leading / no trailing non-numeric characters.
The following is a regex expression has two checks:
It targets all non-numeric characters from the start of the string -- it stops immediately before the first encountered digit, if there is one at all.
It matches/consumes the first encountered whole integer, then immediatelly forgets/releases it (using \K) before matching/consuming ANY encountered characters in the remainder of the string.
My snippet will make 0, 1, or 2 replacements depending on the quality of the string.
Code: (Demo)
$strings = [
'stage', // expect empty string
'8.-10. stage', // expect 8
'8. stage', // expect 8
'8.-10. stage 1st', // expect 8
'Test 8. stage 2020', // expect 8
'Test 8.-10. stage - 2020 test', // expect 8
'A1B2C3D4D5E6F7G8', // expect 1
'1000', // expect 1000
'Test 2020', // expect 2020
];
var_export(
preg_replace('/^\D+|\d+\K.*/', '', $strings)
);
Or: (Demo)
preg_replace('/^\D*(\d+).*/', '$1', $strings)
Output:
array (
0 => '',
1 => '8',
2 => '8',
3 => '8',
4 => '8',
5 => '8',
6 => '1',
7 => '1000',
8 => '2020',
)

Remove quotes from start and end of string in PHP

I have strings like these:
"my value1" => my value1
"my Value2" => my Value2
myvalue3 => myvalue3
I need to get rid of " (double-quotes) in end and start, if these exist, but if there is this kind of character inside String then it should be left there. Example:
"my " value1" => my " value1
How can I do this in PHP - is there function for this or do I have to code it myself?
The literal answer would be
trim($string,'"'); // double quotes
trim($string,'\'"'); // any combination of ' and "
It will remove all leading and trailing quotes from a string.
If you need to remove strictly the first and the last quote in case they exist, then it could be a regular expression like this
preg_replace('~^"?(.*?)"?$~', '$1', $string); // double quotes
preg_replace('~^[\'"]?(.*?)[\'"]?$~', '$1', $string); // either ' or " whichever is found
If you need to remove only in case the leading and trailing quote are strictly paired, then use the function from Steve Chambers' answer
However, if your goal is to read a value from a CSV file, fgetcsv is the only correct option. It will take care of all the edge cases, stripping the value enclosures as well.
I had a similar need and wrote a function that will remove leading and trailing single or double quotes from a string:
/**
* Remove the first and last quote from a quoted string of text
*
* #param mixed $text
*/
function stripQuotes($text) {
return preg_replace('/^(\'(.*)\'|"(.*)")$/', '$2$3', $text);
}
This will produce the outputs listed below:
Input text Output text
--------------------------------
No quotes => No quotes
"Double quoted" => Double quoted
'Single quoted' => Single quoted
"One of each' => "One of each'
"Multi""quotes" => Multi""quotes
'"'"#";'"*&^*'' => "'"#";'"*&^*'
Regex demo (showing what is being matched/captured): https://regex101.com/r/3otW7H/1
trim will remove all instances of the char from the start and end if it matches the pattern you provide, so:
$myValue => '"Hi"""""';
$myValue=trim($myValue, '"');
Will become:
$myValue => 'Hi'.
Here's a way to only remove the first and last char if they match:
$output=stripslashes(trim($myValue));
// if the first char is a " then remove it
if(strpos($output,'"')===0)$output=substr($output,1,(strlen($output)-1));
// if the last char is a " then remove it
if(strripos($output,'"')===(strlen($output)-1))$output=substr($output,0,-1);
As much as this thread should have been killed long ago, I couldn't help but respond with what I would call the simplest answer of all. I noticed this thread re-emerging on the 17th so I don't feel quite as bad about this. :)
Using samples as provided by Steve Chambers;
echo preg_replace('/(^[\"\']|[\"\']$)/', '', $input);
Output below;
Input text Output text
--------------------------------
No quotes => No quotes
"Double quoted" => Double quoted
'Single quoted' => Single quoted
"One of each' => One of each
"Multi""quotes" => Multi""quotes
'"'"#";'"*&^*'' => "'"#";'"*&^*'
This only ever removes the first and last quote, it doesn't repeat to remove extra content and doesn't care about matching ends.
This is an old post, but just to cater for multibyte strings, there are at least two possible routes one can follow. I am assuming that the quote stripping is being done because the quote is being considered like a program / INI variable and thus is EITHER "something" or 'somethingelse' but NOT "mixed quotes'. Also, ANYTHING between the matched quotes is to be retained intact.
Route 1 - using a Regex
function sq_re($i) {
return preg_replace( '#^(\'|")(.*)\1$#isu', '$2', $i );
}
This uses \1 to match the same type quote that matched at the beginning. the u modifier, makes it UTF8 capable (okay, not fully multibyte supporting)
Route 2 - using mb_* functions
function sq($i) {
$f = mb_substr($i, 0, 1);
$l = mb_substr($i, -1);
if (($f == $l) && (($f == '"') || ($f == '\'')) ) $i = mb_substr($i, 1, mb_strlen( $i ) - 2);
return $i;
}
You need to use regular expressions, look at:-
http://php.net/manual/en/function.preg-replace.php
Or you could, in this instance, use substr to check if the first and then the last character of the string is a quote mark, if it is, truncate the string.
http://php.net/manual/en/function.substr.php
How about regex
//$singleQuotedString="'Hello this 'someword' and \"somewrod\" stas's SO";
//$singleQuotedString="Hello this 'someword' and \"somewrod\" stas's SO'";
$singleQuotedString="'Hello this 'someword' and \"somewrod\" stas's SO'";
$quotesFreeString=preg_replace('/^\'?(.*?(?=\'?$))\'?$/','$1' ,$singleQuotedString);
Output
Hello this 'someword' and "somewrod" stas's SO
If you like performance over clarity this is the way:
// Remove double quotes at beginning and/or end of output
$len=strlen($output);
if($output[0]==='"') $iniidx=1; else $iniidx=0;
if($output[$len-1]==='"') $endidx=-1; else $endidx=$len-1;
if($iniidx==1 || $endidx==-1) $output=substr($output,$iniidx,$endidx);
The comment helps with clarity...
brackets in an array-like usage on strings is possible and demands less processing effort than equivalent methods, too bad there isnt a length variable or a last char index

When to use strtr vs str_replace?

I'm having a hard time understanding when strtr would be preferable to str_replace or vice versa. It seems that it's possible to achieve the exact same results using either function, although the order in which substrings are replaced is reversed. For example:
echo strtr('test string', 'st', 'XY')."\n";
echo strtr('test string', array( 's' => 'X', 't' => 'Y', 'st' => 'Z' ))."\n";
echo str_replace(array('s', 't', 'st'), array('X', 'Y', 'Z'), 'test string')."\n";
echo str_replace(array('st', 't', 's'), array('Z', 'Y', 'X'), 'test string');
This outputs
YeXY XYring
YeZ Zring
YeXY XYring
YeZ Zring
Aside from syntax, is there any benefit to using one over the other? Any cases where one would not be sufficient to achieve a desired result?
First difference:
An interesting example of a different behaviour between strtr and str_replace is in the comments section of the PHP Manual:
<?php
$arrFrom = array("1","2","3","B");
$arrTo = array("A","B","C","D");
$word = "ZBB2";
echo str_replace($arrFrom, $arrTo, $word);
?>
I would expect as result: "ZDDB"
However, this return: "ZDDD"
(Because B = D according to our array)
To make this work, use "strtr" instead:
<?php
$arr = array("1" => "A","2" => "B","3" => "C","B" => "D");
$word = "ZBB2";
echo strtr($word,$arr);
?>
This returns: "ZDDB"
This means that str_replace is a more global approach to replacements, while strtr simply translates the chars one by one.
Another difference:
Given the following code (taken from PHP String Replacement Speed Comparison):
<?php
$text = "PHP: Hypertext Preprocessor";
$text_strtr = strtr($text
, array("PHP" => "PHP: Hypertext Preprocessor"
, "PHP: Hypertext Preprocessor" => "PHP"));
$text_str_replace = str_replace(array("PHP", "PHP: Hypertext Preprocessor")
, array("PHP: Hypertext Preprocessor", "PHP")
, $text);
var_dump($text_strtr);
var_dump($text_str_replace);
?>
The resulting lines of text will be:
string(3) "PHP"
string(27) "PHP: Hypertext Preprocessor"
The main explanation:
This happens because:
strtr: it sorts its parameters by length, in descending order, so:
it will give "more importance" to the largest one, and then, as the subject text is itself the largest key of the replacement array, it gets translated.
because all the chars of the subject text have been replaced, the process ends there.
str_replace: it works in the order the keys are defined, so:
it finds the key “PHP” in the subject text and replaces it with: “PHP: Hypertext Preprocessor”, what gives as result:
“PHP: Hypertext Preprocessor: Hypertext Preprocessor”.
then it finds the next key: “PHP: Hypertext Preprocessor” in the resulting text of the former step, so it gets replaced by "PHP", which gives as result:
“PHP: Hypertext Preprocessor”.
there are no more keys to look for, so the replacement ends there.
It seems that it's possible to achieve the exact same results using either function
That's not always true and depends on the search and replace data you provide. For example where the two function differ see: Does PHP str_replace have a greater than 13 character limit?
strtr will not replace in parts of the string that already have been replaced - str_replace will replace inside replaces.
strtr will start with the longest key first in case you call it with two parameters - str_replace will replace from left to right.
str_replace can return the number of replacements done - strtr does not offer such a count value.
I think strtr provides more flexible and conditional replacement when used with two arguments, for example: if string is 1, replace with a, but if string is 10, replace with b. This trick could only be achieved by strtr.
$string = "1.10.0001";
echo strtr($string, array("1" => "a", "10" => "b"));
// a.b.000a
see : Php Manual Strtr.
Notice in manual
STRTR--
Description
string strtr ( string $str , string $from , string $to )
string strtr ( string $str , array $replace_pairs )
If given three arguments, this function returns a copy of str where ...
STR_REPLACE--
...
If search or replace are arrays, their elements are processed first to last.
...
STRTR each turn NOT effect to next, BUT STR_REPLACE does.

Categories