Java 什么是尝试文本文件的东西,为这一数字部分?
新编辑** 我正试图解析一个名为stuff.make的文件中包含的以下行Java 什么是尝试文本文件的东西,为这一数字部分?,java,Java,新编辑** 我正试图解析一个名为stuff.make的文件中包含的以下行 [Utilize 1x Bolt to Helicopter until 10s] [Utilize Boat until 5s] [Utilize 7x Bolt to Helicopter until 2s] [Utilize 4x Wrench to Tank until 3s] 编辑**想要输出(我的目标输出): 在第一个正则表达式中,您错过了Silver: 在第二个正则表达式中,您错过了之后的x(\\d*) 编
[Utilize 1x Bolt to Helicopter until 10s]
[Utilize Boat until 5s]
[Utilize 7x Bolt to Helicopter until 2s]
[Utilize 4x Wrench to Tank until 3s]
编辑**想要输出(我的目标输出):
在第一个正则表达式中,您错过了
Silver:
在第二个正则表达式中,您错过了之后的x
(\\d*)
编辑
添加?
的新正则表达式仅适用于前一个字符。因此,要使其正常工作,您需要将到
组合在一起,使整个单词成为可选的。为了简化您的正则表达式,我将\s
放入组中
Pattern p3 = Pattern.compile("(?:to\\s)?(\\w*)\\suntil\\s(\\d+)s\\]");
编辑
在评论中,有人问我为什么使用\s
而不是空格。我想我会更容易在答案中解释。简单地说,我更喜欢使用\s
,除非我有理由不这么做。\s
匹配任何空格字符,使空格、制表符或其他空格字符与正则表达式匹配。有了这一点,请意识到\s
将使您的正则表达式稍微灵活一些,但代价是不知道匹配的确切字符。还要注意,不同的正则表达式引擎可以以不同的方式实现\s
,这就是我前面提到的“其他空白字符”的原因
那么您什么时候会在\s
语法上使用空格呢
如果不希望正则表达式与空格以外的任何字符匹配。这在某些情况下可能是有效的,但这确实取决于正则表达式的要求。也许这是一段关键的代码,你不想碰任何与你期望完全相符的东西
所有这一切并不是说你不能选择空格而不是\s
。只要理解其中的差别,你就能做出明智的选择
下面是一个关于\s
字符的注释
编辑
在while循环中,该类不能以您试图使用它的方式使用。下面是您需要如何重新组织该部分
while (scan.hasNextLine()) {
s = scan.nextLine();
}
请注意,在阅读该行之前,它正在检查以确保有另一行可用
编辑
这是我的测试程序、输入文件和输出。我修改了这个以匹配输出,你也修改了这个问题。这里的主要变化是我修改了代码,只需要一个正则表达式。你可以用两个来完成这项工作,但是知道你想要完成什么,我认为这是一种更干净的方式来完成它。正则表达式仍然非常简单。这只是两个组之间的合并,我让两个捕获组可选来处理不同的文本
我做的其他事情是清理代码并修复你的bug。请花点时间看看这些变化并理解它们。主要的事情是我重新组织了try/catch
块,并添加了finally
块。所以,坐下来读一读关于正确处理资源和尝试捕获的内容是值得的
下面的链接将显示正则表达式,它为您提供了一个很好的分类。应该有助于你理解我写的正则表达式
还有我收到的输出
1
Bolt
Helicopter
10
---
Boat
5
---
7
Bolt
Helicopter
2
---
4
Wrench
Tank
3
---
感谢您的检查。而((s2=scan.hasNextLine())!=null){s2=scan.nextLine();};是否正确?@OM:删除
!=空
,它应该是正确的。hasNextLine()
函数返回一个布尔值。很抱歉,我不小心放了s2。一开始没有s2。您能检查一下您建议的更正是否仍然是问题的答案吗?@OM:它已更新,但老实说,只需将s2
重命名为您所拥有的变量即可。我假设它是s
,所以只需将s2
替换为s
。用更正注释了原始帖子,并尝试了它,但我仍然在逐行读取文件时遇到相同的错误:“错误:输入字符串:”“”
while (scan.hasNextLine()) {
s = scan.nextLine();
}
public static void main(String[] args) throws IOException {
Parser("C:\\Users\\Nathan.DOZIERINC\\Downloads\\test.txt");
}
public static void Parser(String Path) //Got the path of stuff.make
{
File f = new File(Path);
Scanner scan = null;
//Notice I combined the two try/catches you had and included a finally. The way you were
//doing this would have caused issues when the file was not found. So please read up on using try/catch/finally.
try {
scan = new Scanner(f);
while (scan.hasNextLine()) {
String s = scan.nextLine();
Pattern p1 = Pattern.compile("(?:(?<count>\\d+)x)?\\s(?<type>[\\w]+)(?:\\sto\\s(?<secondType>\\w+))?\\suntil\\s(?<seconds>\\d+)s\\]");
Matcher m1 = p1.matcher(s);
while (m1.find()) {
String count = m1.group("count");
String type = m1.group("type");
String secondType = m1.group("secondType");
String seconds = m1.group("seconds");
//If count is null, that means the regex didn't find this OPTIONAL group
if (count != null)
System.out.println(count);
//I'm not checking for null on type simply because the regex will fail
// if this group is not found.
System.out.println(type);
//If secondType is null, that means the regex didn't find this OPTIONAL group
if (secondType != null)
System.out.println(secondType);
//I'm not checking for null on type simply because the regex will fail
// if this group is not found.
System.out.println(seconds);
System.out.println("---");
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
//Here it prints out the error: Error while reading file line by line: For input string: ""
System.out.println("Error while reading file line by line: " + e.getMessage());
} finally {
//ALWAYS clean up your resources, you were not doing this in the original
if (scan != null) {
scan.close();
}
}
}
[Utilize 1x Bolt to Helicopter until 10s]
[Utilize Boat until 5s]
[Utilize 7x Bolt to Helicopter until 2s]
[Utilize 4x Wrench to Tank until 3s]
1
Bolt
Helicopter
10
---
Boat
5
---
7
Bolt
Helicopter
2
---
4
Wrench
Tank
3
---