I have an url in this format:
http://www.example.com/path?param1=value1¶m2=value2
I need a regex to match the path and params1 and params2 in any order but if param3 is present then I need it to fail so:
String str1 = "/path?param1=value1¶m2=value2"; // This will match
String str2 = "/path?param2=value2¶m1=value1"; // This will match
String str3 = "/path?param1=value1¶m2=value¶m3=value3"; // This will not match
So for I've tried using lookarounds to match the parameters but it is failing:
/path\?(?!param3)(?=param1=.*)(?=param2=.*)
Any thoughts?
P.D. For the curious I'm trying to match a specific URL from an AndroidManifest.xml file https://developer.android.com/guide/topics/manifest/data-element.html
Try this one out:
^(?!.*param3)(?=.*param1=)(?=.*param2=).*$
https://regex101.com/r/rI1lH5/1
If you want the path in as well, then
^\/path(?!.*param3)(?=.*param1=)(?=.*param2=).*$
This started as a comment and I got a little carried away. You can sanitize the query and see if it matches the parameters you need it to and avoid regex all together (if possible)
private boolean checkProperQueryString(String url, String[] requiredKeys){
try{
UrlQuerySanitizer sanitizer = new UrlQuerySanitizer(url);
// Check that you have the right number of parameters
List<UrlQuerySanitizer.ParameterValuePair> parameters =
sanitizer.getParameterList();
if(parameters == null || parameters.size() != requiredKeys.length)
return false;
// Check to make sure that the parameters you have are the
// correct ones
for(String key : requiredKeys){
if(TextUtils.isEmpty(sanitizer(getValue(key))
return false;
}
// We pass every test, success!
return true;
} catch(Exception e){
// Catch any errors (haven't tested this so not sure of errors)
e.printStackTrace();
return false;
}
}
You can then make the call doing something like this
boolean validUrl = checkProperQueryString(url, new String[]{"param1", "param2"});
This doesn't directly answer your question, again just too much for a comment :P
Let me know if this just adds confusion for anyone and I can remove it.
The regex provided by Michael works well but there is a glitch. It also evaluates newParam. So we should change that with:
^(?!.*(\\?|&)param3)(?=.*(\\?|&)param1=)(?=.*(\\?|&)param2=).*$
Basically we check if the parameter name starts with a ? or &. Also if you want to make a parameter optional then you can just put a ? at the end like:
(?!.*(\\?|&)param3)(?=.*(\\?|&)param1=)(?=.*(\\?|&)param2=)?.*$
In the above param2 is optional.
I am comparing file names in a folder ,I want to remove some part of string and check whether name exists or not
Here is my file name :
file1Name:AB-05012_MM-AB_585859_01
file2Name:AB-05012_MM-AB_732320_01-1
Now i want to compare the string only till
AB-05012_MM-AB_732320_01 ignore '-1'
Here is my logic
if (file1Name.equals(file2Name.contains(""))){
list.add(file1Name);
}
When you know there is an extra character in second file name then why not using
fileName2.startsWith ( fileName1)
or
int indexOfDot = fileName1.lastIndexOf(".");
fileName2.startsWith ( fileName1.subString( 0, indexOfDot)
But this is very specific to your problem. or for the cases where
fileName2 = fileName1 + any character or digit
You can try this:
String myStr = str.substring(0, str.lastIndexOf("-1"));
if your file name is same length:
if (file1Name.equals(file2Name.substring(0,24))){
//if same to some task
}
else:
if (file1Name.equals(file2Name.substring(0,file2Name.lastIndexOf('-')))){
//if same to some task
}
And I think the second solution better.
Using Java 1.6 Filepath can be entered by user and then I apply various regular expressions to remove characters that are invalid for the platform (such as '?' is invalid on Windows), and check path length to ensure we end up with a valid filepath for the OS before trying to create the filepath.
But there are two problems:
Its a pain working out what is valid or not for each platform.
I'm making assumptions based on default filesystem for the platform, but of course an OSX system could be writing to a non-mac filesystem such a FAT32, in which case these checks will not be valid.
So I was hoping there would be a better way to do it with NIO2 in Java 7, but haven't found a solution yet, is there one ?
Depending on your expected result (corrected String? Invalid character position? Exception?), this should give you an idea of what can be done:
import java.io.File;
import java.nio.file.InvalidPathException;
public class Test {
public static final void main(final String[] args) {
final String current = new File(".").toPath().toAbsolutePath().normalize().toFile().toString();
Test.correctPath(current);
Test.correctPath(current + "aValidExpression");
Test.correctPath(current + "aValidExpression?;:-&é");
Test.correctPath(current + "aValidExpr//ession?;:-&é");
Test.correctPath(current + "aValidExpre\\ssion?;:-&é");
}
public static final String correctPath(final String path) {
try {
final String returnValue = new File(path).toPath().toAbsolutePath().normalize().toFile().toString();
System.out.println(returnValue);
return returnValue;
} catch (final InvalidPathException e) {
System.err.println(e.getMessage());
final int errorIndex = e.getIndex();
final String newPath = path.substring(0, errorIndex - 1) + path.substring(errorIndex + 1);
return Test.correctPath(newPath);
}
}
}
I hope it helps.
The key to your question is the phrase "remove characters that are invalid for the platform". The various String to Path conversion functions, such as get() and resolve(), will tell you whether the string was valid as a path, but the won't tell why it's invalid. One way of being invalid is to contain invalid characters. Another would be to have, say, too many slash characters together. Regardless, the library does not give any more information than this; it provides no facility to assist in validating user input in any way that would help a user fix an input error. This ought to be a standard practice, admittedly, but it's hardly a practice at all.
Upshot: You'll have to write such a validation library yourself if you want to have one. Upside: You certainly aren't the only person with such a problem.
I guess you should look at Path.getPath
public static Path get(String first,
String... more)
getPath("/foo","bar","gus")-->/foo/bar/gus
Converts a path string, or a sequence of strings that when joined form a path string, to a Path. If more does not specify any elements then the value of the first parameter is the path string to convert. If more specifies one or more elements then each non-empty string, including first, is considered to be a sequence of name elements (see Path) and is joined to form a path string. The details as to how the Strings are joined is provider specific but typically they will be joined using the name-separator as the separator. For example, if the name separator is "/" and getPath("/foo","bar","gus") is invoked, then the path string "/foo/bar/gus" is converted to a Path. A Path representing an empty path is returned if first is the empty string and more does not contain any non-empty strings.
This question already has answers here:
How to get the filename without the extension in Java?
(22 answers)
Closed 9 years ago.
I am trying to get name of a File object without its extension, e.g. getting "vegetation" when the filename is "vegetation.txt." I have tried implementing this code:
openFile = fileChooser.getSelectedFile();
String[] tokens = openFile.getName().split(".");
String name = tokens[0];
Unfortunately, it returns a null object. There is a problem just in the defining the String object, I guess, because the method getName() works correctly; it gives me the name of the file with its extension.
Do you have any idea?
If you want to implement this yourself, try this:
String name = file.getName();
int pos = name.lastIndexOf(".");
if (pos > 0) {
name = name.substring(0, pos);
}
(This variation doesn't leave you with an empty string for an input filename like ".txt". If you want the string to be empty in that case, change > 0 to >= 0.)
You could replace the if statement with an assignment using a conditional expression, if you thought it made your code more readable; see #Steven's answer for example. (I don't think it does ... but it is a matter of opinion.)
It is arguably a better idea to use an implementation that someone else has written and tested. Apache FilenameUtils is a good choice; see #slachnick's Answer, and also the linked Q&A.
If you don't want to write this code yourself you could use Apache's FilenameUtils.
FilenameUtils.getBaseName(openFile.getName());
This will return the filename minus the path and extension.
I prefer to chop off before the last index of "." to be the filename.
This way a file name: hello.test.txt is just hello.test
i.e.
int pos = filename.lastIndexOf(".");
String justName = pos > 0 ? filename.substring(0, pos) : filename;
You need to handle there being no extension too.
String#split takes a regex. "." matches any character, so you're getting an array of empty strings - one for each spot in between each pair of characters.
http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#split(java.lang.String)
There are two problems with your code...
1) Just using "." as an argument to split is being interpreted as a Rejex that you don't want. You want a literal dot. So you have to escape it...
openFile.getName().split("\\.");
2) You will incorrectly parse any file with more than one dot. The best way to do this is to search for the last dot and get the substring...
int pos = openFile.getName().lastIndexOf(".");
if(pos != -1) {
String name = openFile.getName().substring(0, pos);
}
You can try split("\\.");. That is, basically escaping the . as it's treated as all characters in regex.
This question already has answers here:
Is there a way in Java to determine if a path is valid without attempting to create a file?
(7 answers)
Closed 7 years ago.
In my Java application I am renaming files to a file name provided in a String parameter. There is a method
boolean OKtoRename(String oldName, String newName)
which basically checks whether the newName isn't already taken by some other file, as I wouldn't want to bury existing ones.
It now occurred to me that perhaps the newName String will not denote a valid file name. So I thought to add this check to the method:
if (new File(newName).isFile()) {
return false;
}
Which obviously isn't the right way to do it, since in most cases the newFile does not yet exist and therefore although it is OKtoRename, the function returns false.
I was wondering, is there a method (I know there isn't for the java.io.File objects) like canExist()? Or would I have to resort to regex to make sure the newFile String does not contain invalid characters (e.g. ?, *, ", :)? I wonder if there is perhaps a function hidden somewhere in the JDK that would tell me if a string could possibly denote a valid file name.
I assembled a list of illegal filename characters (considering UNIX, Mac OS X and Windows systems) based on some online research a couple of months ago. If the new filename contains any of these, there's a risk that it might not be valid on all platforms.
private static final char[] ILLEGAL_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };
EDIT:
I would like to stress, that this is not a complete solution: as a commenter pointed out, even though it passes this test your file name could still be a Windows specific keyword like COM, PRN, etc. However, if your file name contains any of these characters, it will certainly cause trouble in a cross-platform environment.
Use createNewFile(), which will atomically create the file only if it doesn't yet exist.
If the file is created, the name is valid and it is not clobbering an existing file. You can then open the files and efficiently copy data from one to the other with FileChannel.transferXXX operations.
An important thing to keep in mind that, in general, the check and the creation should be atomic. If you first check whether an operation is safe, then perform the operation as a separate step, conditions may have changed in the meantime, making the operation unsafe.
Additional food for thought is available at this related post: "Move/Copy operations in Java."
Update:
Since this answer, the NIO.2 APIs have been introduced, which add more interaction with the file system.
Suppose you have an interactive program, and want to validate after each keystroke whether the file is potentially valid. For example, you might want to enable a "Save" button only when the entry is valid rather than popping up an error dialog after pressing "Save". Creating and ensuring the deletion of a lot of unnecessary files that my suggestion above would require seems like a mess.
With NIO.2, you can't create a Path instance containing characters that are illegal for the file system. An InvalidPathException is raised as soon as you try to create the Path.
However, there isn't an API to validate illegal names comprised of valid characters, like "PRN" on Windows. As a workaround, experimentation showed that using an illegal file name would raise a distinct exception when trying to access attributes (using Files.getLastModifiedTime(), for example).
If you specify a legal name for a file that does exist, you get no exception.
If you specify a legal name for a file that does not exist, it raises NoSuchFileException.
If you specify an illegal name, FileSystemException is raised.
However, this seems very kludgey and might not be reliable on other operating systems.
Here system specific way is suggested.
public static boolean isFilenameValid(String file) {
File f = new File(file);
try {
f.getCanonicalPath();
return true;
} catch (IOException e) {
return false;
}
}
If developing for Eclipse, check out org.eclipse.core.internal.resources.OS
public abstract class OS {
private static final String INSTALLED_PLATFORM;
public static final char[] INVALID_RESOURCE_CHARACTERS;
private static final String[] INVALID_RESOURCE_BASENAMES;
private static final String[] INVALID_RESOURCE_FULLNAMES;
static {
//find out the OS being used
//setup the invalid names
INSTALLED_PLATFORM = Platform.getOS();
if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
//valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
INVALID_RESOURCE_CHARACTERS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
"com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
"lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
Arrays.sort(INVALID_RESOURCE_BASENAMES);
//CLOCK$ may be used if an extension is provided
INVALID_RESOURCE_FULLNAMES = new String[] {"clock$"}; //$NON-NLS-1$
} else {
//only front slash and null char are invalid on UNIXes
//taken from http://www.faqs.org/faqs/unix-faq/faq/part2/section-2.html
INVALID_RESOURCE_CHARACTERS = new char[] {'/', '\0',};
INVALID_RESOURCE_BASENAMES = null;
INVALID_RESOURCE_FULLNAMES = null;
}
}
/**
* Returns true if the given name is a valid resource name on this operating system,
* and false otherwise.
*/
public static boolean isNameValid(String name) {
//. and .. have special meaning on all platforms
if (name.equals(".") || name.equals("..")) //$NON-NLS-1$ //$NON-NLS-2$
return false;
if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
//empty names are not valid
final int length = name.length();
if (length == 0)
return false;
final char lastChar = name.charAt(length-1);
// filenames ending in dot are not valid
if (lastChar == '.')
return false;
// file names ending with whitespace are truncated (bug 118997)
if (Character.isWhitespace(lastChar))
return false;
int dot = name.indexOf('.');
//on windows, filename suffixes are not relevant to name validity
String basename = dot == -1 ? name : name.substring(0, dot);
if (Arrays.binarySearch(INVALID_RESOURCE_BASENAMES, basename.toLowerCase()) >= 0)
return false;
return Arrays.binarySearch(INVALID_RESOURCE_FULLNAMES, name.toLowerCase()) < 0;
}
return true;
}
}
Just something i found, in java 7 and later, there is a class called Paths that has a method called get that takes one or more Strings and throws
InvalidPathException - if the path string cannot be converted to a Path
This is how I implemented this:
public boolean isValidFileName(final String aFileName) {
final File aFile = new File(aFileName);
boolean isValid = true;
try {
if (aFile.createNewFile()) {
aFile.delete();
}
} catch (IOException e) {
isValid = false;
}
return isValid;
}
To me it appears to be an OS dependent problem. You may simply want to check for some invalid character in the file name. Windows does this when you try to rename the file, it pops a message saying that a file cannot contain any of the following characters: \ / : * ? < > |
I am not sure if your question is "is there a library doing the job for me?" in that case I don't know any.
Using
String validName = URLEncoder.encode( fileName , "UTF-8");
File newFile = new File( validName );
Does the work.
I have just found today. I'm not sure if it works 100% of the time, but so far, I have been able to create valid file names.