How to use split() to remove last destination in path? - java

I have a list of paths and i need to remove the last directory of each path.
Path : "I:\Directory_1\Directory_2\Directory_3-Sometext"
I used the split method to remove everyting on the right side of the '-'
I've tried using split() removing one by one and then regrouping everything in one string.
I've tried splitting everyting on ("\") and using lenght()
//Removes text after '-'
String [] parts = path.split("-")
String partsA = parts[0]
String [] newParts = partsA.split("\\\\");
String partsB = newParts[newParts.length-1];
partsA = partsA.substring(partsA.length()-partsB.length(),partsA.length()+partsB.length());
I expect the ouput to be
\Directory_1\Directory_2
without the last directory and the text

Instead of using string manipulation, you could use proper path/file objects, with the additional benefit that it can handle other types of paths (for example a unix path such as /home/directory1):
String f = "I:\\Directory_1\\Directory_2\\Directory_3-Sometext";
Path p = Paths.get(f);
Path parent = p.getParent();
System.out.println(parent.toString());

You could also use Java's File API:
new File("I:\\Directory_1\\Directory_2\\Directory_3-Sometext").getParent();
This has the advantage of being OS indepenent...

Use:
String directory = "I:\\Directory_1\\Directory_2\\Directory_3-Sometext";
directory.substring(0, directory.lastIndexOf("\\"));
which outputs:
I:\Directory_1\Directory_2

Related

How to elegantly parse a string to have exactly what you need?

I currently have a S3 bucket directory key like this:
String dir = "s3://mybucket/workflow/science/sweet-humoor/vars";
What I am trying to do is to get the prefix of this S3 directory, a prefix is actually without s3:://mybucket/, so what I want to have is workflow/science/sweet-humoor/vars
Now, what would be a elegant way to achieve this? I know the quickest way to do is to do a subString(13), but this will break whenever the bucket name changes.
How would you handle this?
Use a regular expression with replaceAll:
String result = directoryKey.replaceAll("s3://[^/]+/", "");
The regex here is:
s3://[^/]+/
It matches the part that you want to remove, which is s3:// followed by a bunch of non-slash characters, followed by a slash.
It's cleanest to use the Java library functions for paths instead of handling the Strings directly. What you have is an URL, so
URL url = new URL(dir);
URI uri = url.toURI();
Path fullpath = Paths.get(uri);
Now you have a Path (ie the "/mybucket/workflow/science/sweet-humoor/vars" part), and you can get the subpath by
// start index 1 to skip the first directory element
Path subpath = fullpath.subpath(1, fullpath.getNameCount()-1);
You can make a File out of this (subpath.toFile()), or just get the path string by
subpath.toString();
The URIBuilder class from the org.apache.http.client.utils package can do that.
URIBuilder builder = new URIBuilder(dir);
String thePath = builder.getPath();
This automatically extracts /workflow/science/sweet-humoor/vars from the path. The retrieved path does not include mybucket, because URIBuilder sees the first part immediately after the protocol specifier (s3://) as hostname.
Further processing can be done through Path p = Paths.get(thePath).
You can try this:
String dir2=dir.replaceAll("s3://"+dir.split("/")[2]+"/","");
String dir = "s3://mybucket/workflow/science/sweet-humoor/vars";
dir = dir.replace("//", "").substring( dir.indexOf("/") );
System.err.println(dir); // prints mybucket/workflow/science/sweet-humoor/vars
I would split the string by "/" and get the values from third index and join it with "/". Sample code in python.
input_string = "s3://mybucket/workflow/science/sweet-humoor/vars"
list1 = (input_string.split("/"))
print(list1)
print("/".join(list1[3:]))
Output:
workflow/science/sweet-humoor/vars

Create a function for File.separator using Pattern Matcher

A static analysis tool when running on my java project gives "Portability Flaw In File Separator" error and I need to fix it. In my code, I have fileUnsafe. I want to use a method to convert it into fileSafe (explained below).
// Case 1
//no platform independence, good for Unix systems
File fileUnsafe = new File("tmp/abc.txt");
//platform independent and safe to use across Unix and Windows
File fileSafe = new File("tmp"+File.separator+"abc.txt");
Similarly for paths like -
// Case 2
//no platform independence, good for Unix systems
File fileUnsafe = new File("/tmp/abc.txt");
// platform independent and safe to use across Unix and Windows
File fileSafe = new File(File.separator+"tmp"+File.separator+"abc.txt");
I have multiple of these file addresses throughout my project and I need to create some conversion method that could just take in this path as a string, append File.separator to it, and return it. Something like this -
File fileSafe = new File(someConversionMethod("/tmp/abc.txt"));
I tried this method but it gives me NullPointerException on case 2.
public static String someConversionMethod(String target) {
Pattern ptr = Pattern.compile("[\\\\\\\\|/]+");
Matcher mtr = ptr.matcher(target);
return mtr.replaceAll(File.separator + "" + File.separator);
}
Any help either fixing this method or suggesting a graceful way to handle this situation would be appreciated.
nit - I referred to Replacing character with File.separator using java.regex Pattern Matcher but it didn't really help my case.
I would try splitting the string at the file separator into an array like so.
String str = "/tmp/abc.txt";
String result = "";
String rgx = "\\\\|/";
String [] arrOfStr = str.split(rgx);;
Then you can add your File.separator back in using a for loop. Like this:
for (int i = 1; i < arrOfStr.length ; i++)
result += File.separator + arrOfStr[i];
I start from index one because the first slash gets doubled in the resulting string.
Since this is a one time change, you could use the regex find and replace in Eclipse
For the first case:
use Regex: ^File\sfileUnsafe\s=\snew File\(\"(?<folder1>[^\/]+)\/(?<fileName>[^\.]+)(?<extension>\.\w{3})\"\);
Replace with: File fileSafe = new File("${folder1}"+File.separator+"${fileName}${extension}");
Demo
For the second case:
use Regex: ^File\sfileUnsafe\s=\snew File\(\"\/(?<folder1>[^\/]+)\/(?<fileName>[^\.]+)(?<extension>\.\w{3})\"\);
Replace with: File fileSafe = new File(File.separator+"${folder1}"+File.separator+"${fileName}${extension}");
Demo
if you have more than one folder, you could continue this pattern and fix them.
I admit, this is not a clean straight forward way, but will get the job done.

Java how to handle a \ on input

I am currently trying to split a String folder. I get the value from a file system and it usually looks something like EAM\Testing.
String folder = "EAM\Testing"
String[] parts = folder.split("\\");
I know \ has special rules to it in java.
String folder = "EAM\\Testing"
String[] parts = folder.split("\\\\");
(I know the code above would work if I could control what the input looked like)
My problem is that I can not control what string folder is as input from a location of a file.
Is there a way to get this to work where folder only has one \ in it?
This is for a recycle bin component I am writing for Documentum a enterprise management system. When a document is deleted and the folder doesn't exist anymore I want to recreate it and inorder to recreate it the folder names must be seperate as I have to create them one at a time.
Here is how I get the name of the folder.
File f = new File(relationRecord.getRepeatingString(
"dp_original_folder_paths",
i));
(This gives an input such as \EAM\testing
String folder1 = f.toString();
I then get rid of the first \ by
String folder = folder1.substring(1);
Which gives me EAM\testing
Well if this is literally a file path, you should consider using the Path class, it'll make your life easier.
Path path = Paths.get("C:\\home\\joe\\foo");
System.out.format("toString: %s%n", path.toString());
System.out.format("getFileName: %s%n", path.getFileName());
System.out.format("getName(0): %s%n", path.getName(0));
System.out.format("getNameCount: %d%n", path.getNameCount());
System.out.format("subpath(0,2): %s%n", path.subpath(0,2));
System.out.format("getParent: %s%n", path.getParent());
System.out.format("getRoot: %s%n", path.getRoot());
Your second option
String[] parts = folder.split("\\\\");
Should work fine for your input string. When you write a string literal like "EAM\\Testing", the resulting string has only one slash. You can read some details on escape sequences in Java there.
The reason you need four slashes in split is because \ is an escape character both for string literals and regular expressions (String#split accepts regular expression as its argument)
You should be doing something like this -
String s = "EAM\\testing";
String a[] = s.split("\\\\");
Here you duplicate the backslash once for the String (since \ is an escape character for String) and again for the regex for the same reason.
Your question seems to be "how can I remove a leading \ from a string:
folder = folder.replaceAll("^\\\\", "");
This searches for a back slash at the start if the string, and if found replaces it with nothing (ie deletes it).
Regarding backslash vs forward slash characters in paths, java handles both.

Concatenating to a file name before the ‘.’ Filename extension in Java

I can’t seem to find a way of concatenating to a file name before the “.” extension in Java and I’m not entirely sure how I would go about this.
I have already tried:
String s = r + "V1";
Where the variable r contains the value of myFile.txt and the output is: myFile.txtV1, but what I need to achieve is myFileV1.txt as I don’t want to overwrite the existing file with the same name but concatenate the V1 before the . filename extension when the file is written.
Thanks
In case file name can contain more then one dot like foo.bar.txt you should find index of last dot (String#lastIndexOf(char) can be useful here).
To get file name without extension (foo.bar part) substring(int, int) full file name from index 0 till index of that last dot.
To get extension (.txt part from last dot till the end of string) substring(int) from last dot index.
So your code can look like:
int lastDotIndex = r.lastIndexOf('.');
String s = r.substring(0, lastDotIndex ) + "V1" + r.substring(lastDotIndex);
Another approach is to use Apache Commons IO's FilenameUtils class to get the file's base name and extension.
import org.apache.commons.io.FilenameUtils;
...
File file = ...
String filename = file.getName();
String base = FilenameUtils.removeExtension(filename);
String extension = FilenameUtils.getExtension(filename);
String result = base + "-something-here" + "." + extension;
Look at String.indexOf() and String.substring() to split the string up and rebuild your updated version.
Try this (assuming that you have only one '.' in the name of your file):
String[] x = r.split("\\.");
String s = x[0]+"V1."+x[1];
Another apache commons method based on StringUtils.substringBeforeLast() and StringUtils.substringAfterLast:
String newPath = StringUtils.substringBeforeLast(filePath, ".") +
"_updated." + StringUtils.substringAfterLast(filePath, ".");
NB: You still need to check if the file actually contains the dot character or otherwise the result won't be consistent.
String s = r.substring(0,r.indexOf(".")) + "V1" + r.substring(a.indexOf("."));
Reminder that extensions are technically platform specific. Also, you probably want to have separate variables for the name and extension and combine them together at the end. Last caveat is that this code will not work if there are multiple period symbols in the filename (e.g. hello.world.txt)

Remove file prefix in absolute path but prefix is also directory part

I was wondering if there is any nice solution for the following problem:
Assuming I have a string with the absolute Path to a file and the file has the prefix "temp_".
I am able to trim the prefix with string.replaceFirst().
But if I am unlucky "temp_" is also part of the directory in that String.
How to make sure only the last occurence will get trimmed?
I can only think to parse it myself, but was wondering if there's magic left to do it a better way?
To be more precisely as example:
C:\Dump\sol1\temp_results\temp_2012-04-core.pcap
Should become:
C:\Dump\sol1\temp_results\2012-04-core.pcap
If you use Path.getFileName(), only the base name of the file is returned (ie, it does not include any parent directory). You can do your substitution with that and put it back together using other Path functions (see getName(), subpath(), etc) into either another Path or a single String.
if you have got it is a File id defo use #goldilocks' approach. But if for some reason you simply have it as a String, first thing that popped into my head is this:
String target = "temp_";
String fullPath = "C:/Dump/sol1/temp_results/temp_2012-04-core.pcap";
StringBuffer sb = new StringBuffer(fullPath);
int end = fullPath.lastIndexOf(target) + target.length();
System.out.println(sb.replace(fullPath.lastIndexOf(target), end, ""));
This is just another example How to do it.
devide total String into three parts.
1.substring till temp_ last occurence
2.last occuerence of temp_
3.substring after last occuerence of temp_
cancat 1+3 anyway I recommend #goldilocks solution

Categories