PHP trim() issue - php

Lets say I have $url="../folder/file" and I want to find and remove the ../ part.
I'm using trim() …
$url = trim($url,"../");
… but it gives me a warning:
Warning: trim() [function.trim]: Invalid '..'-range, no character to the left of '..' on line above
What I did wrong?

what you did wrong was fail to read the manual:
With .. you can specify a range of characters.
<?php
$url="../folder/file";
$url = trim($url,"\.\./");
echo $url;
?>

you can use ltrim
echo ltrim("../folder/file", "./");
or
echo trim("../folder/file", "./");

There is a special syntax in the trim function from php.net/trim that allows you to specify a range, which is what the interpreter believes you are doing because of the '..'
// trim the ASCII control characters at the beginning and end of $binary
// (from 0 to 31 inclusive)
$clean = trim($binary, "\x00..\x1F");
var_dump($clean);
The second argument to trim should be a string of characters that would be stripped, so you should not have to put the '.' twice.

The second argument to the trim function specifies a list of characters to be stripped, not a multi-character string. The function interprets '..' as an operator specifying a range of characters (like a..z or 1..5). You can strip out the '../' in a number of ways, but one easy one is this:
$parts = explode('/', $url);
array_shift($parts);
$url = implode('/', $parts);

I found this function in bottom comments of the trim page on php.net that seem to do what you want
function trimString($input, $string){
$input = trim($input);
$startPattern = "/^($string)+/i";
$endPattern = "/($string)+$/i";
return trim(preg_replace($endPattern, '', preg_replace($startPattern,'',$input)));
}

Related

How to replace last backward slash with forward slash PHP

I want to replace my last \ with / on this URL string
C:\wamp\www\chm-lib\sekhelp_out\HTML\AS_BUILD.htm
I have tried this link, but no changes, I am missing something, please correct me where I am wrong.
Here is a solution using PHP's string functions instead of regex.
Do this:
$url = 'C:\wamp\www\chm-lib\sekhelp_out\HTML\AS_BUILD.htm';
$pos = strrpos($url, '\\');
$url = substr_replace($url, '/', $pos, 1);
echo $url;
To get this:
C:\wamp\www\chm-lib\sekhelp_out\HTML/AS_BUILD.htm
Explanation:
Get the position of the last \ in the input string using strrpos()
Replace that with / using substr_replace()
Note
It is important to pass '\\' instead of '\' to strrpos() as the first \ escapes the second.
Also note that you can shorten the code above to a single line if you prefer, but I thought it would be easier to understand as is. Anyway, here is the code as a one-liner function:
function reverseLastBackslash($url) {
return substr_replace($url, '/', strrpos($url, '\\'), 1);
}
You can try exploding the string as an array and imploding after popping off the last part, and connecting it back with a forward slash.
$array = explode('\','C:\wamp\www\chm-lib\sekhelp_out\HTML\AS_BUILD.htm');
$last = array_pop($array);
$corrected = implode('\',$array) . '/' . $last;
The backslash escaping is tricky:
preg_replace('/\\\\([^\\\\]*)$/', '/$1', "C:\\wamp\\www\\chm-lib\\sekhelp_out\\HTML\\AS_BUILD.htm")
You have to escape once for the literal string and once for the regular expression so a single \ needs to be \\\\ (1 x 2 x 2)
Simply use this
str_replace('\\','/','C:\wamp\www\chm-lib\sekhelp_out\HTML\AS_BUILD.htm');

Find string pattern from end

I am trying to find if a string is of a format <initial_part_of_name>_0.pdf i.e.
Find if it ends with .pdf (could be eliminated using rtrim)
The initial part is followed by an _ underscore.
The underscore is followed by a whole number (0, 1, 2, ... , etc.)
What could be the optimum way to achieve this? I have tried combinations of the string functions strpos (to find the position. but could not get to do anything from the end of the string).
Any pointers would be appreciated!
Edit:
Sample strings:
public://Big_Data_Tutorial_part4_0.pdf
public://Big_Data_Tutorial_part4_1.pdf
public://Big_Data_Tutorial_part4_3.pdf
The reason why I need to check is to avoid duplicate files which are stored with the _<number> appended.
You can use preg_match() function for matching patterns
Check the function preg_match()
preg_match("/(.*)_(\d+)\.pdf$/", "<initial_part_of_name>_0.pdf",$arr);
In $arr[1], you will get the <initial_part_of_name>
in $arr[2], you will get the number after underscore
a non-array and regex way
$str1 = "public://Big_Data_Tutorial_part4_0a.pdf"; // no match because 0a
$str2 = "public://Big_Data_Tutorial_part4_1.pdf"; // match
$str3 = "public://Big_Data_Tutorial_part4_3.pdf"; // match
$last_part = strrchr($str1, "_");
if (trim(strstr($last_part, ".", true), "_0..9") == "" && strstr($last_part, ".") == ".pdf") {
echo "match";
}
$str = '<initial_part_of_name>_0.pdf';
$exploded = explode('.', $str);
echo $exploded[1];
This could be done using regex. Something like
^[0-9A-Za-z]+\_[\d]\.pdf$
Implementation:
$filename = '<initial_part_of_name>_0.pdf';
if(preg_match('/^[0-9A-Za-z]+\_[\d]\.pdf$/i', $filename)){
// name pattern Matched
}
SOLUTION 2
use pathinfo()
$filename = '<initial_part_of_name>_0.pdf';
$path_parts = pathinfo($filename);
if(strtolower($path_parts['extension']) == 'pdf') {
if(preg_match('/.*_[\d]$/', $path_parts['filename'])){
// name pattern Matched
}
} else {
// Not a PDF file
}

How to make so chunk_split doesn't add something at the end of the string

i'm using chunk_split to add a "-" every 4th letter, but it also add one at the end of the string, which i don't want, here's the code:
<?php
function GenerateKey($input)
{
$generated = strtoupper(md5($input).uniqid());
echo chunk_split(substr($generated, -24), 4, "-");
}
?>
Maybe not the most efficient way to generate a serial key, i think it would be better if i used mt_rand, but i think it'll do for now.
So how would i do so it doesn't add a "-" at the end of the string?
Because right now the output looks like this:
89E0-1E2E-1875-3F63-6DA1-1532-
Really appreciate the help i can get
Kind regards,
Jesper
You can remove the trialing - by rtrim. Try this
$str = "89E01E2E18753F636DA11532";
echo rtrim(chunk_split($str,4,"-"), "-");
Output:
89E0-1E2E-1875-3F63-6DA1-1532
You can chop off the - with rtrim():
echo rtrim(chunk_split(substr($generated, -24), 4, "-"), "-");
md5() generates a 32-character string.
uniqid() by default generayes a 13-character string.
You want a 24-character string with delimiting hyphens between every four characters.
You don't need to trim a trailing hyphen if you reconfigure earlier processing.
Generate the random string and prepend 3 arbitrary characters.
Call chunk_split() to apply hyphens.
Cut away the unwanted characters from the front of the string and the trailing hyphen.
Convert the isolated string to uppercase.
Return the value from your function instead of echoing.
Code: (Demo)
function GenerateKey(string $input): string
{
return strtoupper(
substr(
chunk_split(
'...' . md5($input) . uniqid(),
4,
'-'
),
-25,
24
)
);
}
echo GenerateKey('foooobar');

PHP rtrim ".php"

I want to remove ".php" from the end of a string if it exists. Consider this:
$filename = 'index';
rtrim($filename,".php");//returns "index"
$filename = 'search';
rtrim($filename,".php");//returns "searc"
Why is this happening? I feel like it has something to do with ending with the letter 'h' - 'h' being in the string in rtrim. So I tried a regular expression (.php$) to see if it made a difference but it didn't.
rtrim accepts a list of characters as the second argument, so in this case, it will trim not just the .php extension, but any ., p, or h characters found in the rest of the string.
Try using preg_replace("/(.+)\.php$/", "$1", $filename); instead, or basename($filename, '.php') if you have the file on the server, not just in a string.
The second argument to rtrim is a string with a list of characters. In this case, it will strip off any P, H, and . in your string, so returning searc.
if you're simply trying to remove the extension, why not use this:
$filename = 'index.php';
$name = strstr($filename, '.', true);

Regular Expression to Remove Beginning and End chars from a string?

Let's say I have a string like so:
$file = 'widget-widget-newsletter.php';
I want to use preg_replace() to remove the prefix widget- and to remove the suffix .php . Is it possible to use one regular expression to achieve all this?
The resulting string should be widget-newsletter.
$file = preg_replace('/^widget-|\.php$/', '', $file);
Why not use substr? Much simpler and faster.
Don't think of it as stripping off the ends, rather as extracting the middle:
$file = 'widget-widget-newsletter.php';
if (preg_match('/^widget\-(.+)\.php$/i', $file, $matches))
echo "filename is " . $matches[1][0];
Of course, if "widget-" and ".php" are entirely static and are always going to be there, you could just use substr:
echo "filename is " . substr($file, 7, -4);
That would be much faster but if you pass it garbage, you'll get garbage back.
$name = preg_replace(array('%^widget-%', '%-%', '%\.php$%'), array('','_',''), $file);
should do it.
Or more general (assuming the prefix goes to the first - and the suffix starts at the last .):
$name = preg_replacearray('%^.*?-%', '%-%', '%\.(?!.*?\.).*?$%'), array('','_',''), $file);
If you provide an array of patterns and an array of replacements to the function, then each pattern gets replaced by the according replacement.
Update:
As you removed the requirement to replace the - by _, substr() is indeed better suited:
$name = substr($file, 7, -4);
From the manual description of the replacement parameter:
The string or an array with strings to replace. If this parameter is a string and the pattern parameter is an array, all patterns will be replaced by that string.
Sounds like you could use an array with the prefix and suffix patterns in it for the pattern parameter, and just put empty string as the replacement.

Categories