我正在尝试使用Java中的Scanner类扫描一个文件,其中的数据字段由“@”或“endline”分隔。以下是一个示例输入文件:
Student @ Codey @ Huntting
Student @ Sarah @ Honsinger
为了正确扫描如下所示的输入文件,我尝试将Java扫描程序上的分隔符更改为正则表达式“[@\\v]”
,它应该匹配@
或任何垂直空白,包括\n
和\r
下面是我用来测试它的代码:
Scanner scanner = new Scanner(new File("data/initialize.txt"));
int tokenNum = 0;
scanner.useDelimiter("[@\\v]");
while(scanner.hasNext()) {
System.out.println("Token #" + tokenNum++ + ": " + scanner.next());
}
scanner.close();
我希望扫描的令牌是:
Token #1: Student
Token #2: Codey
Token #3: Huntting
Token #4: Student
Token #5: Sarah
Token #6: Honsinger
但实际收到的代币是:
Token #1: Student
Token #2: Codey
Token #3: Huntting
Token #4
Token #5: Student
Token #6: Sarah
Token #7: Honsinger
Token #8:
我本来希望扫描器在扫描hunting
时,在搜索之后,以及在下一次调用input时,向上移动到换行符。next()
,跳过该换行符,但由于某种原因,扫描程序似乎在该行末尾捕获了一个空字符串。
我检查了多次,文件在任何一行之后都没有空格。我尝试过不同的模式,如[@[\\v]]]
和[@][\\v]
,但这些模式总是给出具有相同空字符串错误的数据,或者输出完全不正常。
您的文件可能包含形式\r\n
的换行符。在这种情况下,扫描仪会找到分隔符\r
并输出\r
之前的任何内容。然后它找到分隔符\n
并输出\r
和\n
之间的空令牌,然后在\n
之后继续。
为了允许\r\n
中断,我建议您将\r\n |[@\v]
按该确切顺序作为分隔符regex。当然,在转义之后,它会变成“\r\n|[@\\v]”
。
正如Andreas提到的,您可以使用的另一个正则表达式是@\R
,因为\R
匹配任何unicode换行符,包括\R\n
。这可能是最好的解决方案。
如果我理解正确,我们可能只想删除@
和后面的空格,然后用新行替换它,并在它前面附加一个文本。也许,这个表达会有帮助:
([\S\s]*?)(?:@\s|$)
如果不需要此表达式,可以在regex101.com.中修改/更改表达式
您还可以在jex.im可视化您的表情:
这个片段显示我们可能有一个有效的表达式:
const regex = /([\S\s]*?)(?:@\s|$)/gm;
const str = `Student @ Codey @ Huntting
Student @ Sarah @ Honsinger`;
const subst = `\n$1`;
// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);
console.log('Substitution result: ', result);
您的问题是换行符是一对\r\n
,并且\v
单独匹配它们。为了复制这一点,让我们更改代码,为测试数据使用内联字符串:
String input = "Student @ Codey @ Huntting\r\n" +
"Student @ Sarah @ Honsinger\r\n";
try (Scanner scanner = new Scanner(input).useDelimiter("[@\\v]")) {
for (int tokenNum = 0; scanner.hasNext(); tokenNum++) {
System.out.println("Token #" + tokenNum + ": \"" + scanner.next() + "\"");
}
}
输出
Token #0: "Student "
Token #1: " Codey "
Token #2: " Huntting"
Token #3: ""
Token #4: "Student "
Token #5: " Sarah "
Token #6: " Honsinger"
Token #7: ""
解决此问题的一种方法是首先尝试匹配\r\n
对:
useDelimiter("\r\n|[@\\v]")
输出
Token #0: "Student "
Token #1: " Codey "
Token #2: " Huntting"
Token #3: "Student "
Token #4: " Sarah "
Token #5: " Honsinger"
但是,这将花费时间检查两次\r
,因此最好使用内置\r
(任何Unicode换行符序列,相当于\u000D\u000A |[\u000A\u000B\u000C\u000D\u0085\u2028\u2029]
):
useDelimiter("@|\\R")
同样的结果,但更清楚地反映了你想如何匹配。
您当然可以使用trim()
或bar()
来删除前导空格和尾随空格,但是为什么不让Scanner
来完成这项工作呢?使用|
需要一个(非捕获)组来保持它与空白匹配分开:
useDelimiter("\\s*(?:@|\\R)\\s*")
输出
Token #0: "Student"
Token #1: "Codey"
Token #2: "Huntting"
Token #3: "Student"
Token #4: "Sarah"
Token #5: "Honsinger"
问题内容: 我正在使用嵌套循环从字符串行(从文本文件)中提取数字,如下所示: 问题在于此代码将跳过所有空格,但是我也需要使用这些“空格”。那么可以返回空格还是我需要使用其他东西? 我的文本文件可能包含以下内容: 这些空白行各包含1条,这就是我需要返回的行。 问题答案: 使用扫描仪和方法,您将找到解决方案,因为这将使您能够捕获空白行或空白行。
问题内容: 我正在编写一个使用Event类的程序,该类中有一个日历实例和一个String类型的描述。创建事件的方法使用扫描仪获取月,日,年,小时,分钟和说明。我遇到的问题是Scanner.next()方法仅返回空格之前的第一个单词。因此,如果输入为“我的生日”,则该事件实例的描述就是“我的”。 我做了一些研究,发现人们使用Scanner.nextLine()解决此问题,但是当我尝试这样做时,它只是
我正试图用Java中的扫描器将一个字符串分成另外两个字符串。好像不起作用。我只能通过谷歌找到扫描仪用来读取控制台输入的例子。我从扫描仪的手册中找出了我做事情的方式,我不确定我错了什么。 第一个和第二个是空白的,我不知道为什么。
问题:编写一个名为wordWrap的方法,该方法接受表示输入文件的扫描器作为其参数,并将文件的每一行输出到控制台,对超过60个字符的所有行进行文字包装。例如,如果一行包含112个字符,则方法应将其替换为两行:一行包含前60个字符,另一行包含最后52个字符。包含217个字符的行应该被包装成四行:三行的长度为60,最后一行的长度为37。 我的代码: 输出中的问题: 预期产出: 生产产量: 我哪里做错了
我试图为字符串创建一个扫描器方法,它只在用户输入的值不为空时才返回该值(空白,用户立即点击“Enter”等)。如果用户这样做,我希望打印出一条错误消息,并让循环再次返回开始,等待新的用户输入。如果正确,我希望方法返回正确的输入值。 我的代码是这样的:
问题内容: 我试图找到一种方法来从键盘输入。 我尝试使用: 该方法不存在。 我尝试了作为。但是,它并不总是在每种情况下都可行,因为我从我的方法中调用的另一个方法需要作为输入。因此,我必须找到一种显式将char作为输入的方法。 有什么帮助吗? 问题答案: 你可以从中提取第一个字符: 消耗正好一个字符,你可以使用: 要严格使用一个字符,可以使用: