I have a system which will store certain files for various websites.
Some websites are shown as basic:
www . myrandomsite . com
www . yetanothersite . com /sublevel/
http: somefunky.sub . org
...and so forth.
I wanted to convert these to folder names in the safest and most sensible way.
What I have so far:
preg_replace('/[^A-Za-z0-9 ]/', '-', 'www.yetanothersite.com/sublevel/');
returns: string(32) "www-yetanothersite-com-sublevel-"
This is hardly a pretty folder name though, but on the right track.
Given the diversity of domain name formats, I wanted to create the cleanest and simplest possible solution.
Need some advice.
Try the following:
$urls = array('www.myrandomsite.com', 'http://somefunky.sub.org', 'http://www.yetanothersite.com/sublevel/', 'http://stackoverflow.com/users///1401975/');
// PHP 5.3+ IS A MUST
$folders = preg_replace_callback('#(?<protocol>(https?|ftp)://)|(?<end>/+(?=$))|(?<replace>/+)#', function($m){
if(isset($m['protocol'][1])){return '';}
if(isset($m['end'][0])){return '';}
return '-';
}, $urls);
print_r($folders);
Output:
Array
(
[0] => www.myrandomsite.com
[1] => somefunky.sub.org
[2] => www.yetanothersite.com-sublevel
[3] => stackoverflow.com-users-1401975
)
The script will:
remove the http, https, ftp protocol
remove the last forward slash
replace the rest of the forward slashes with a hyphen.
Related
I am currently trying to create a random image generator in PHP, and I'm having a hard time setting the file path, I can get all the file paths, but they are in one long string, like this.
" ../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG"
with the " .." marking the beginning of a new file.
How would i explode ( or something of the kind ) each file_path to return them separately?
Here is one way you can do this.
$data = '../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG';
$files = preg_split('/(?<!^)(?=\.{2})/', $data);
print_r($files);
Output
Array
(
[0] => ../images/box1/IMG_3158.JPG
[1] => ../images/box1/IMG_3161.JPG
[2] => ../images/box1/IMG_3163.JPG
[3] => ../images/box1/IMG_3158.JPG
[4] => ../images/box1/IMG_3161.JPG
[5] => ../images/box1/IMG_3163.JPG
)
Regular Expression:
(?<! look behind to see if there is not:
^ the beginning of the string
) end of look-behind
(?= look ahead to see if there is:
\.{2} '.' (2 times)
) end of look-ahead
<?php
//Since new file path is starting from ".." we explode it using ".." and added to each file path.
$string ="../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG";
$file_path=explode('..',$string);
$i=0;
while(isset($file_path[++$i])){
$file_path[$i]="..".$file_path[$i];
echo $file_path[$i]."<br />";
}
?>
http://ideone.com/MTRr9Q
Just use explode()
$file_paths = explode('..', $input);
Example
$string = "../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG../images/box1/IMG_3158.JPG../images/box1/IMG_3161.JPG../images/box1/IMG_3163.JPG";
$file_paths = explode('..', $string);
var_dump($file_paths);
This strips of the ".." at the beginning, so try to append it yourself. For more complicated situations, a preg_split() would be an appropriate task. Given that your string doesn't change, then an explode could do.
If you are able to introduce an otherwise unused character between each path as you import(?) the list of path names, you could then use that character as your delimiter instead of ".." (refer to Ali's answer).
I have URLs like so:
http://localhost/hi-every-body/
http://s1.localhost/hello-world/
http://s2.localhost/bye-world/
I want the page "slug" from the URLS, eg.
hi-every-body
hello-world
bye-world
What's a simple way of doing this in PHP?
This should do exactly that:
trim(parse_url($url, PHP_URL_PATH), '/');
It takes the path and strips the forward slashes on both sides.
To get only the last part of the path:
basename(parse_url($url, PHP_URL_PATH));
A possibly more robust solution is this:
$slugs = explode("/", $_GET['params']);
This will give you an array filled with every element in your URL.
Eg. http://localhost/one/hippo/cake?t=21
Becomes the array:
Array (
[0] => one
[1] => hippo
[2] => cake
)
This allows you to use each element as you require.
I have a string, /controller/method/parameter1/parameter2?parameter1=parameter2. This is just the REQUEST_URI I am using for my website.
I want to split this string into separate array elements using PHP, and the following code works fine for this action: preg_split('[/]', $_SERVER['REQUEST_URI'], NULL, PREG_SPLIT_NO_EMPTY).
This works almost perfectly, providing me with an excellent array output, until I add get variables. With these, the last array element includes the get variables too.
My question is, is there a way to stop processing as soon as a question mark (?) is reached?
I want to cut it from the question mark, and only show items before the question mark. This (hopefully) will mean that this:
Array
(
[0] => controller
[1] => method
[2] => parameter1
[3] => parameter2?parameter1=parameter2
)
Will become this:
Array
(
[0] => controller
[1] => method
[2] => parameter1
[3] => parameter2
)
The problem is, I want this all in the regular expression. I don't really care if there is another way (I know there is), I just want to know if there is a way to do this in the regex.
Thanks
Explode before split
$vars = explode('?', $_SERVER['REQUEST_URI']);
$array = preg_split('[/]', $vars[0], NULL, PREG_SPLIT_NO_EMPTY);
UPDATE
From php.net:
If you don't need the power of regular expressions, you can choose
faster (albeit simpler) alternatives like explode() or str_split().
In your case you can use str_split and save some time.
you can replace ?(.*) using:
preg_split('[/]',
preg_replace("/\?(.*)/", "", $_SERVER['REQUEST_URI']),
NULL, PREG_SPLIT_NO_EMPTY)
I do this in my system with strpos and substr before using regex:
$uri = $_SERVER['REQUEST_URI'];
$uri = ($pos = strpos($uri, '?')) ? substr($uri, 0, $pos) : $uri;
I'm trying to make a main menu bar link dynamic, based on the visitor's current page.
I started with
$path = $_SERVER['REQUEST_URI'];
Which, of course, returns things like
/subfolder/page.html
/subfolder1/subfolder2/page.html
/page.html
I need to grab whatever is after the first '/'. I've tried messing around with explode, but I stumble with what to do with the resulting array. I'm also going cross-eyed trying to write a regex - seems a more elegant solution.
Then I need to build my switch. Something along the lines of:
switch ($path)
{
case '/subfolder0':
$link = $root_url.'/subfolder0/anotherfolder/page.html';
break;
case '/subfolder1':
$link = $root_url.'/subfolder1/page.html';
break;
default:
$link = $root_url.'/subfolder2/page.html';
}
Finally, should I be using if...elseif for this in lieu of switch?
Thanks for your time, all!
To grab everything after the first /:
strstr($_SERVER['REQUEST_URI'], '/');
Or, with regex:
preg_match('#(/.*)#', $_SERVER['REQUEST_URI'], $matches); // $matches[1] will be the path
As far as the switch, I'd say if/elseif/else is the least-elegant in your case, switch isn't bad, but personally I'd go with an associative array:
$mapping = array('/subfolder0' => $root_url.'/subfolder0/anotherfolder/page.html', 'etc' => 'etc');
$link = $mapping($path);
This lets you keep the mapping in another file for organization, and makes it a little bit easier to maintain by separating configuration from implementation.
Using explode is not at all a bad idea if you are interested in all the parts of the URI, you should take a look at the documentation for explode
Its usage would be like so:
$exploded = explode('/','/path/to/page.html');
echo $exploded[0]; // Will print out '' (empty string)
echo $exploded[1]; // Will print out 'path'
echo $exploded[2]; // Will print out 'to'
echo $exploded[3]; // Will print out 'page.html'
However as far as I understand, you are looking to replace the link by whatever is after the first character (which is always '/'), you could use substr like so:
// Get whatever is after the first character and put it into $path
$path = substr($_SERVER['REQUEST_URI'], 1);
In your case, it is not needed because you are able to predict there is a backslash at the beginning of the string.
I would also suggest using an associative array to replace the URL.
I would implement the entire thing like so (removing the first backslash as you require):
// Define the URLs for replacement
$urls = array(
'subfolder0' => '/subfolder0/anotherfolder/page.html',
'subfolder1' => '/subfolder1/page.html'
);
// Get the request URI, trimming its first character (always '/')
$path = substr($_SERVER['REQUEST_URI'], 1);
// Set the link according to $urls associative array, or set
// the default URL if not found
$link = $urls[$path] or '/subfolder2/page.html';
Or with explode, taking only the first part of the URI:
// Get the parts of the request
$requestParts = explode('/', $_SERVER['REQUEST_URI']);
// Set the link according to $urls associative array, or set
// the default URL if not found
$link = $urls[$requestParts[1]] or '/subfolder2/page.html';
After analyzing the OP's question, I think he/she meant to phrase it as "Everything after the first '/', but before the second '/'. Here is what I got:
You could try this regex:
<?php
/*
* Regex: /((\w+?|\w+\.\w+?)(?!^\/))(?=\/.*$|$)/
*/
$paths = array(
'/subfolder9/',
'/subfolder/page.html',
'/subfolder1/subfolder2/page.html',
'/page.html'
);
foreach ($paths as $path) {
preg_match("/((\w+?|\w+\.\w+?)(?!^\/))(?=\/.*$|$)/", $path, $matches);
debug($matches);
}
// $matches[1] will contain the first group ( ) matched in the expression.
// or "subfolder<#>" or "<page>.<ext>"
// The loop results is as follows:
Array
(
[0] => subfolder9
[1] => subfolder9
[2] => subfolder9
)
Array
(
[0] => subfolder
[1] => subfolder
[2] => subfolder
)
Array
(
[0] => subfolder1
[1] => subfolder1
[2] => subfolder1
)
Array
(
[0] => page.html
[1] => page.html
[2] => page.html
)
?>
Note: This only works with regex flavors that support look-arounds (zero-width positive & negative look ahead are the ones used the example.)
This a great cheat sheet for regular expressions and I don't code without it.
Regular-Expressions.info - (click to view)
You can just use dirname function to get what you want:
$path = dirname('/subfolder/page.html'); // returns '/subfolder'
$path = dirname('/subfolder1/subfolder2/page.html'); // returns '/subfolder1'
$path = dirname('page.html'); // returns '.'
EDIT: Regex based solution:
$path = preg_replace('#^(/[^/]*).*$#', '$1', '/subfolder/page.html' )
Let's say I might have a couple of directories stored in a string.. they might look like this
/something/WHATEVER/websites/dev/tools/tests/media/upload.ini
/something/WHATEVER/websites/dev/tools/tests/get/add.ini
etc.
How can I extract the names "media" and "get" from those two links up there? I would probably have to use regular expressions but how would it look like?
Use php function explode? http://php.net/manual/en/function.explode.php
$str="one ,two , three , four ";
print_r(array_map('trim',explode(",",$str)));
Output:
Array ( [0] => one [1] => two [2] => three [3] => four )
If you want to use regexes, it might look like this
/([^/]+)/[^/]+$
i.e.,
preg_match('`/([^/]+)/[^/]+$`',$fullpath,$matches)
$matches[1] will contain your directory.
I would normally suggest sscanf for such easy patterns:
$string = '/something/WHATEVER/websites/dev/tools/tests/media/upload.ini';
$format = '/something/WHATEVER/websites/dev/tools/tests/%[^/]';
$r = sscanf($string, $format, $name);
Next to that there are standard PHP dirname functions that are helpful in case you need this more dynamic, e.g. the last directory name of a filename:
$string = '/something/WHATEVER/websites/dev/tools/tests/media/upload.ini';
$reduce = explode('/', dirname($string));
$name = end($reduce);
Demo