In my text files I can have both path elements (like a) and paths (like a.b.c). The fact that path and path element can be ambiguous is giving me headaches.
If I have lexer elements like this
PATH : PATH_ELEMENT('.'PATH_ELEMENT)* ;
PATH_ELEMENT : [a-zA-Z_][a-zA-Z0-9_]* ;
and I have source text
dir : a
path1 : a.b.c
path2 : a
If I use PATH for both then it will work, but it will not flag an error if dir has a segmented path.
If I swap the order of the lexer items and use PATH_ELEMENT for dir and PATH for pathX then the first two will work OK but then path2 will match PATH_ELEMENT when it is expecting PATH.
How can I achieve this?
Related
I have a string which contains a path to a file:
C:\Users\user\directory\build.bat
Is there a way I can remove the word between the last backslash and the second last backslash (in this case it is directory), however I would like a way to do this several times:
First time I run the code the path should look like this:
C:\Users\user\build.bat
If I run the code on the new string I just got from running the program the first time, the output should be like this:
C:\Users\build.bat
Yes, this is very much possible. I propose the following pattern:
^(.+)\.-\(.-)$ - this will match the entire path, matching first the directories up to the parent directory and then the filename. Use it as follows:
local function strip_parent_dir(path)
local path_to_parent, filename = path:match[[^(.+)\.-\(.-)$]]
return path_to_parent .. "\\" .. filename
end
which can then be used as follows:
print(strip_parent_dir[[C:\Users\user\directory\build.bat]]) -- C:\Users\user\build.bat
print(strip_parent_dir(strip_parent_dir[[C:\Users\user\directory\build.bat]])) -- C:\Users\build.bat
another option would be to split the path by the path delimiter (backslash), inserting the parts into a table, then removing the penultimate entry, finally concatenating the parts; this is slightly longer but may be considered more readable (and it may have better asymptotic performance):
local function strip_parent_dir(path)
local parts = {}
for part in path:gmatch"[^\\]+" do
table.insert(parts, part)
end
table.remove(parts, #parts - 1)
return table.concat(parts, "\\")
end
the results are the same. Choose whatever you consider more readable.
private void setDirectory(String directory) {
directory = "file:///" + directory.replace("\\", "/").replaceAll(" ", "%20");
this.directory = directory;
}
That is how I am taking the directory inputs,along with the help of FileChooser class's method showOpenMultipleDialog(null). This bit of code is working just fine. What I just don't understand is why are paths like "D:/Music/The Cure/Disintegration[1988-89]/One more time.mp3" not working when paths like "D:/Music/The Cure/Disintegration(1988-89)/One more time.mp3" are working.
Because the Media constructor argument is a URI and square brackets are reserved characters in a URI, so if you want an actual square bracket, you need to URI encode the input string.
If I have an arbitrary file sent to me, using Node.js, how can I figure out what language it's in? It could be a PHP file, HTML, HTML with JavaScript inline, JavaScript, C++ and so on. Given that each of these languages is unique, but shares some syntax with other languages.
Are there any packages or concepts available to figure out what programming language a particular file is written in?
You'd need to get the extension of the file. Are you getting this file with the name including the extension or just the raw file? There is no way to tell if you do not either get the file name with the extension or to scan the dir it's uploaded to and grabbing the names of the files, and performing a directory listing task to loop through them all. Node has file system abilities so both options work. You need the file's name with extension saved in a variable or array to perform this. Depending on how you handle this you can build an array of file types by extensions optionally you can try using this node.js mime
Example:
var fileExtenstions = {h : "C/C++ header", php : "PHP file", jar : "Java executeable"};
You can either split the string that contains the files name using split() or indexOf() with substring.
Split Example:
var fileName = "hey.h"; // C/C++/OBJ-C header
var fileParts = fileName.split(".");
// result would be...
// fileParts[0] = "hey";
// fileParts[1] = "h";
Now you can loop the array of extensions to see what it is and return the description of the file you set in the object literal you can use a 2d array and a for loop on the numeric index and check the first index to see it's the extension and return the second index(second index is 1)
indexOf Example:
var fileName = "hey.h";
var delimiter = ".";
var extension = fileName.substring( indexOf( delimiter ), fileName.length );
now loop through the object and compare the value
I am trying to use fs.existsSync to check whether a file exists. When the full filesystem path is entered, it returns successfully. When the path contains an environment variable like ~/foo.bar or $HOME/foo.bar, it fails to find the file.
I have tried all of the methods from the path module to massage the path first, but nothing seems to work. I should note that the filepath is entered by the user either via command line or a JSON file.
I am aware that the environment variables live in process.env, but I was wondering if there is some way to handle this aside from a find/replace for every possible variable.
Environment variables are expanded by the shell. Node's fs methods make filesystem calls directly.
Read the variable you need out of process.env and use path.join to concatenate.
path.join(process.env.HOME, 'foo.bar');
(Keep in mind there is no HOME variable on Windows if you need to be cross-platform; I believe it's USERPROFILE.)
Since you're dealing with user input, you're going to have to parse the path components yourself.
First, normalize the input string and split it into an array.
var p = path.normalize(inputStr).split(path.sep);
If the first element is ~, replace it with the home directory.
if (p[0] == '~') p[0] = process.env.HOME || process.env.USERPROFILE; // Windows
Then loop over each element, and if it starts with $, replace it.
for (var i = 0; i < p.length; i++) {
if (p[i][0] == '$') {
var evar = p[i].substr(1);
if (process.env[evar]) p[i] = process.env[evar];
}
}
And finally, join the path array back together, re-normalizing:
path.join.apply(path, p);
Use process.env.HOME instead? Then use path.join to get the correct path.
fs.existsSync(path.join(process.env.HOME,"foo.bar"));
How can I create a java.nio.file.Path object from a String object in Java 7?
I.e.
String textPath = "c:/dir1/dir2/dir3";
Path path = ?;
where ? is the missing code that uses textPath.
You can just use the Paths class:
Path path = Paths.get(textPath);
... assuming you want to use the default file system, of course.
From the javadocs..http://docs.oracle.com/javase/tutorial/essential/io/pathOps.html
Path p1 = Paths.get("/tmp/foo");
is the same as
Path p4 = FileSystems.getDefault().getPath("/tmp/foo");
Path p3 = Paths.get(URI.create("file:///Users/joe/FileTest.java"));
Path p5 = Paths.get(System.getProperty("user.home"),"logs", "foo.log");
In Windows, creates file C:\joe\logs\foo.log (assuming user home as C:\joe)
In Unix, creates file /u/joe/logs/foo.log (assuming user home as /u/joe)
If possible I would suggest creating the Path directly from the path elements:
Path path = Paths.get("C:", "dir1", "dir2", "dir3");
// if needed
String textPath = path.toString(); // "C:\\dir1\\dir2\\dir3"
Even when the question is regarding Java 7, I think it adds value to know that from Java 11 onward, there is a static method in Path class that allows to do this straight away:
With all the path in one String:
Path.of("/tmp/foo");
With the path broken down in several Strings:
Path.of("/tmp","foo");