Java Scanner.nextLine()使用换行符

Java Scanner.nextLine()使用换行符,java,regex,Java,Regex,我安装了一个扫描仪,它正在处理输入流 我正在使用Scanner.nextLine()前进到每一行,然后在每一行上执行一些正则表达式工作 我有一个正则表达式,它基本上类似于[\w\p{Z}]+?[;\n\r]来提取该行末尾的任何内容,或者如果它们是分号分隔的,则只提取一个内容 所以如果我的InpustStream看起来像 abcd; xyz 它将拾取abcd;,但不是xyz 我认为这是因为当调用.nextLine()函数时,scanner正在使用文本行末尾的换行符。有人能告诉我如何解决这个问题吗

我安装了一个扫描仪,它正在处理输入流

我正在使用Scanner.nextLine()前进到每一行,然后在每一行上执行一些正则表达式工作

我有一个正则表达式,它基本上类似于
[\w\p{Z}]+?[;\n\r]
来提取该行末尾的任何内容,或者如果它们是分号分隔的,则只提取一个内容

所以如果我的InpustStream看起来像

abcd;
xyz
它将拾取abcd;,但不是xyz

我认为这是因为当调用.nextLine()函数时,scanner正在使用文本行末尾的换行符。有人能告诉我如何解决这个问题吗

作为补充信息,对于我的正则表达式,我正在使用pattern.DOTALL编译模式


谢谢

那么,为什么不在
nextLine()
结果中添加一个换行符呢


是否存在表示字符串边界的正则表达式特殊字符
^
$
。话虽如此,由于您没有行尾字符,所以很容易在第一个分号之前使用所有内容;只需使用除分号以外的所有内容:

[^;]+
Scanner
使用换行符作为其行为的一部分,因为您通常不想处理它,而且它依赖于系统


编辑:在一条评论中,有人指出您可以使用
line.split(“;”)
并获取第一个值。这也行。

您可以在正则表达式模式中使用
\z
表示输入的结尾,或者使用
$
表示行的结尾。此外,默认情况下,
Scanner.nextLine()
返回不带换行符的行。此外,您还可以更改
扫描仪使用的分隔符,以包括
及其
使用delimiter
方法。最后,您的模式可能不会执行您认为它会执行的操作,因为
\p{Z}
仅捕获字母“Z”。

API明确指定下一行删除任何行分隔符

您可以在其他回复中执行各种建议之一。但也请注意扫描器有带“模式”的方法。因此,如果正则表达式正确,可以使用以下方法:

或者看看你有没有更多的代币

然后


或者,如果上述返回true,则获取令牌。

实际上,您是导致问题的原因,因为您试图使用最后一行末尾的换行符。:/最后一行在没有换行符的情况下突然结束是完全有效的,但是正则表达式要求它有一个换行符。您可以通过使用锚或前瞻来替换新行来解决这个问题,但是有更简单的方法来解决这个问题

一种是覆盖默认分隔符,并使用
next()
在字段上迭代:

另一种方法是使用
nextLine()
(使用默认分隔符)迭代行,然后用分号拆分每行:

Scanner sc2 = new Scanner("abcd;\nxyz");
while (sc2.hasNextLine())
for (String item : sc2.nextLine().split(";"))
{
  System.out.printf("%s%n", item);
}
Scanner的API是我使用过的最臃肿、最不直观的API之一,但如果您记住以下两个关键点,就可以大大减少使用它的痛苦:

  • 考虑匹配分隔符,而不是字段(就像您使用字符串的
    split()
  • 在未首先调用相应的
    hasNextXXX()
    方法之前,切勿调用其中一个
    nextXXX()
    方法

  • 您是否必须为此仅使用正则表达式?似乎
    String.split
    也能做到这一点?很容易找到-停止在每一行上重新登录,检查nextLine()得到了什么…虽然这是一个比较模糊的答案,但我同意。您可以在字符串末尾添加
    \r
    字符。或者只需对整个字符串执行正则表达式(不要使用扫描仪)。这将返回所有的行尾。字符串太大,无法在整件事情上同时使用正则表达式。您误解了文档。请参阅此链接:不,
    \p{Z}
    是一个真正的Unicode类别,它完全没有用处。它包括
    \p{Zl}
    (行分隔符,U+2028)、
    \p{Zp}
    (段落分隔符,U+2029)和
    \p{Zs}
    (空格分隔符),但不包括
    \n
    \r
    。人们实际上用来分隔行和/或段落的字符没有Unicode分类。是的,但是你用Java进行正则表达式匹配,对吗?当使用
    模式时,您不应该使用Java正则表达式语法吗?
    
    Scanner sc2 = new Scanner("abcd;\nxyz");
    while (sc2.hasNextLine())
    for (String item : sc2.nextLine().split(";"))
    {
      System.out.printf("%s%n", item);
    }