我正在用Java编写一个应用程序,它显示文件列表,其中文件名中的第一个单词与用户定义的字符串匹配,然后根据某些首选项删除或重新排列它们。我目前正处于找到找到我的文件的好方法的阶段。使用this Java Tutorial我得到了类似的结果:
Path source = Paths.get(sourceText.getText());
Path dest = Paths.get(destText.getText());
System.out.println("Source:" + source.toString());
System.out.println("P/N: " + partNoText.getText());
String matchString = "glob:**" + partNoText.getText() + "*";
System.out.println("Matching: " + matchString);
fileFinder = new FileFinder(matchString);
try {
Files.walkFileTree(source, fileFinder);
} catch (IOException e1) {
e1.printStackTrace();
}
for (Path path : fileFinder.getResult()) {
System.out.println("Moving: " + path.getFileName());
Path target = Paths.get(dest.toString() + "\\" + path.getFileName());
try {
Files.move(path, target, REPLACE_EXISTING);
} catch (IOException e1) {
e1.printStackTrace();
}
}
其中FileFinder扩展SimpleFileVisitor并具有此visitFile方法:
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
System.out.println(file.toString());
System.out.println(fileMatcher.matches(file));
if (fileMatcher.matches(file)) {
result.add(file);
return FileVisitResult.CONTINUE;
}
return FileVisitResult.CONTINUE;
}
我的问题是,glob会选择文件名中包含零件号的文件。以任何方式。因此,如果我的文件被称为“12345 RevA Really Big Part 2:Electric Bugaloo”,那么如果用户输入“1”或“123”或“Bugaloo”,则该字符串将匹配。理想情况下,只有在用户输入“12345”时才会匹配。
我尝试将我的matchString切换为"regex: .*" + partNoText + "\\b"
,这适用于我从this other Java Tutorial修改的正则表达式测试工具。我究竟做错了什么? PathMatcher
的工作方式与常规Matcher
的工作方式不同吗?
P.S。其中包含“Text”一词的任何变量,如sourceText
和partNoText
都是JTextFields。 Hopefull是代码的唯一部分,从我剪掉它的内容中大部分都不清楚。
答案 0 :(得分:1)
" PathMatcher的工作方式与常规匹配器不同吗?"
是。 PathMatcher
使用文件名 globbing [1] ,而Matcher
使用正则表达式。
请参阅您链接的教程中的What Is a Glob?,并将其与java.util.regex.Pattern的文档进行比较 Globbing与正则表达式匹配相当有限。
如果你有一个严格遵守的严格文件命名约定,你可能会使用globbing(我收回我之前评论的最后一部分)。
我们说你的文件被命名为
numeric part number
- space
- optional revision & space
- description
也就是说,零件号可以有可变数位,但零件号后面的空格是必需的并且始终存在。
所以你的例子" 12345 RevA Really Big Part 2:Electric Bugaloo" 适合与partNum == 12345,revision =" RevA",description ="真的很重要的第2部分:电动Bugaloo"
用户输入部件号P/N: 123
作为变量userPN
,并将glob构造为
String glob = userPN + " *";
导致全局等于"123 *"
这将不匹配12345,如你所愿,因为3之后的空格将与4不匹配。
如果文件名中的部件号后面有不所需的空格,但接下来是总是字母,无论是修订版还是描述版,都可以构建一个glob作为
String glob = userPN + "[A-Z,a-z]*";
给出glob = 123[A-Z,a-z]*
,它也不匹配12345,因为字母必须跟随123而且4不在该字符范围内。
你可以让你的角色范围更复杂,对于可选空间说[A-Z,a-z, ]
,这取决于你的需要,但这一切都归结为你的文件命名约定。您需要非常准确地陈述该惯例并遵守它。
[1]如果您指定"语法" PathMatcher
可以使用正则表达式而不是通配符调用FileSystem.getPathMatcher(String)时为regex
。这就像是
FileSystem fs = FileSystems.getDefault();
PathMatcher pm = fs.getPathMatcher("regex:\\d{5}\\s.*");
答案 1 :(得分:0)
我认为你继续这么复杂的方式。当你不去寻找事件时,为什么你会首先使用拍拍Marc她。
通过文件树和每个目录迭代目录流来匹配你的glob会容易得多。