I have two example filename strings:
jquery.ui.min.js
jquery.ui.min.css
What regex can I use to only match the LAST dot? I don't need anything else, just the final dot.
A little more on what I'm doing. I'm using PHP's preg_split() function to split the filename into an array. The function deletes any matches and gives you an array with the elements between splits. I'm trying to get it to split jquery.ui.min.js into an array that looks like this:
array[0] = jquery.ui.min
array[1] = js
If you're looking to extract the last part of the string, you'd need:
\.([^.]*)$
if you don't want the . or
(\.[^.]*)$
if you do.
I think you'll have a hard time using preg_split, preg_match should be the better choice.
preg_match('/(.*)\.([^.]*)$/', $filename, $matches);
Alternatively, have a look at pathinfo.
Or, do it very simply in two lines:
$filename = substr($file, 0, strrpos($file, '.'));
$extension = substr($file, strrpos($file, '.') + 1);
At face value there is no reason to use regex for this. Here are 2 different methods that use functions optimized for static string parsing:
Option 1:
$ext = "jquery.ui.min.css";
$ext = array_pop(explode('.',$ext));
echo $ext;
Option 2:
$ext = "jquery.ui.min.css";
$ext = pathinfo($ext);
echo $ext['extension'];
\.[^.]*$
Here's what I needed to exclude the last dot when matching for just the last "part":
[^\.]([^.]*)$
Using a positive lookahead, I managed this answer:
\.(?=\w+$)
This answer matches specifically the last dot in the string.
I used this - give it a try:
m/\.([^.\\]+)$/
Related
I have a path "../uploads/e2c_name_icon/" and I need to extract e2c_name_icon from the path.
What I tried is using str_replace function
$msg = str_replace("../uploads/","","../uploads/e2c_name_icon/");
This result in an output "e2c_name_icon/"
$msg=str_replace("/","","e2c_name_icon/")
There is a better way to do this. I am searching alternative method to use regex expression.
Try this. Outputs: e2c_name_icon
<?php
$path = "../uploads/e2c_name_icon/";
// Outputs: 'e2c_name_icon'
echo explode('/', $path)[2];
However, this is technically the third component of the path, the ../ being the first. If you always need to get the third index, then this should work. Otherwise, you'll need to resolve the relative path first.
Use basename function provided by PHP.
$var = "../uploads/e2c_name_icon/";
echo basename( $var ); // prints e2c_name_icon
If you are strictly want to get the last part of the url after '../uploads'
Then you could use this :
$url = '../uploads/e2c_name_icon/';
$regex = '/\.\.\/uploads\/(\w+)/';
preg_match($regex, $url, $m)
print_r ($m); // $m[1] would output your url if possible
You can trim after the str_replace.
echo $msg = trim(str_replace("../uploads/","","../uploads/e2c_name_icon/"), "/");
I don't think you need to use regex for this. Simple string functions are usually faster
You could also use strrpos to find the second last /, then trim off both /.
$path = "../uploads/e2c_name_icon/";
echo $msg = trim(substr($path, strrpos($path, "/",-2)),"/");
I added -2 in strrpos to skip the last /. That means it returns the positon of the / after uploads.
So substr will return /e2c_name_icon/ and trim will remove both /.
You'd be much better off using the native PHP path functions vs trying to parse it yourself.
For example:
$path = "../uploads/e2c_name_icon/";
$msg = basename(dirname(realpath($path))); // e2c_name_icon
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
}
I have a text.
$text='userpics/115/X3WGOC0009JA.jpg';
I want to add a letter p before X3WGOC0009JA.jpg, so my output will be
$text='userpics/115/pX3WGOC0009JA.jpg';
---^
I am new to php, so I don't really know what to try, I was hoping you could guide me in the right direction
You can explode by the slash by one way.
$exploded_text = explode('/', $text);
$new_text = $exploded_text[0] . $exploded_text[1] . 'p' . $exploded_text[2];
It's not the best way, but it will work.
Based on his question, I think all he wants to do is:
$text='userpics/115/'.'p'.'X3WGOC0009JA.jpg';
First, I would get the filename using strrpos and substr:
$text = 'userpics/115/X3WGOC0009JA.jpg';
$prepend_filename = 'p';
$last_slash_pos = strrpos($text, '/');
if ($last_slash_pos === false) throw new Exception('No slashes found');
$path = substr($text, 0, $last_slash_pos);
$filename = substr($text, $last_slash_pos + 1); // Add one to skip slash
And then you can add the p (as specified in $prepend_filename) using this:
$new_path = $path . DIRECTORY_SEPARATOR . $prepend_filename . $filename;
Have you tried just setting you variables and concatenation if you doing this a bunch.
$p = 'p';
$new = "userpics/115/" . $p . "X3WGOC0009JA.jpg";
There is a function, substr_replace(), which can insert a string at a point you want.
We combine this with strRpos() which we can use to find the first slash, LOOKING IN REVERSE:
$string = substr_replace($string, 'p', strrpos($string, '/')+1 );
This will insert 'p' in $string. At the position of the '/' in $string. The +1 corrects the 'cursor' to the character AFTER the slash.
Why not use the explode functions?
Very simple: Those are slow. String functions like strpos() and substr_replace() are VERY fast, especially on small strings.
Arrays are WAY slower in php, so don't go there unless you have to. For simple string- manipulation you should use simple string functions (sounds easy when you put it like that doesnt it?).
In a simple test I benchmarked the explode variant like user3758531's VS the string variant like mine:
100.000 tries with arrays: 1.5 sec
100.000 tries with strings: 0.9 sec
In this one situation, with this one action timing doesnt really matter. But apply this way of thinking thoughout the website and you will notice it speeding up/slowing down.
I'm stuck in my code.
My site's users are supposed to give me the link of a image that I will store in a variable.
How can I check what the link ends with, the extension if you will?
You can use any of these:
$ext = substr(strrchr(FILENAME, '.'), 1);
$ext = substr(FILENAME, strrpos(FILENAME, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', FILENAME);
Their performance differences are negligible (even when ran like a 500 000 times; tested with PHP 7 using phpcb)
The pathinfo() is like... really slow, compared to these, for just getting the (last) extension.
While Jefferson answer is correct; based on the problem an easier solution would be to use PATHINFO_EXTENSION.
pathinfo('/path/to/file/image.jpg', PHPINFO_EXTENSION); // returns 'jpg'
You can use the substring method "substr" to get the last couple characters after the last occuring period which you can find with "strrpos" I believe.
strrpos (See doc here) returns false if the last occurrence wasn't found and the index of the match if it is.
$mystring = 'stackoverflow.png';
$pos = strrpos($mystring,'.');
if($pos === false) { // Note the triple '='
// not found..
}else{
echo substr($mystring, $pos); // print '.png'
}
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.