解释用JAVA编写的这一行

时间:2018-08-31 08:03:55

标签: java java.util.scanner

在HACKERRANK中,此行代码经常发生。我认为这是为了跳过空格,但这"\r\u2028\u2029\u0085"的意思是什么

 scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");

9 个答案:

答案 0 :(得分:6)

Scanner.skip跳过与模式匹配的输入,这里的模式是:-

(\ r \ n | [\ n \ r \ u2028 \ u2029 \ u0085])?

  • ?完全匹配零或前一个字符。
  • |替代
  • []匹配
  • 中出现的单个字符
  • \ r匹配回车符
  • \ n换行符

  • \ u2028匹配具有区分大小写的索引为2018 base 16(8232 base 10或20050 base 8)的字符

  • \ u2029将字符与索引区分为2029 base 16(8233 base 10或20051 base 8)区分大小写
  • \ u0085匹配具有区分大小写的索引85 base 16(133 base 10或205 base 8)的字符
  

第一种替代方法\ r \ n

  • \ r与回车符(ASCII 13)匹配
  • \ n与换行符(ASCII 10)匹配
  

第二个替代项[\ n \ r \ u2028 \ u2029 \ u0085]

  • 匹配[\ n \ r \ u2028 \ u2029 \ u0085]下面列表中存在的单个字符
  • \ n与换行符(ASCII 10)匹配
  • \ r与回车符(ASCII 13)匹配
  • \ u2028从字面上(区分大小写)将分隔符匹配与索引202816(823210或200508)的字符
  • \ u2029按字面意义(区分大小写)将匹配索引202916(823310或200518)的字符与
  • 匹配。
  • \ u0085从字面上匹配具有索引8516(13310或2058)的字符(区分大小写)NEXT LINE

答案 1 :(得分:5)

跳过\r\n用于Windows。

其余为标准\r=CR\n=LF(请参阅\r\n , \r , \n what is the difference between them?

然后是一些Unicode特殊字符:

u2028 = LINE SEPARATORhttps://www.fileformat.info/info/unicode/char/2028/index.htm

u2029 = PARAGRAPH SEPARATORhttp://www.fileformat.info/info/unicode/char/2029/index.htm

u0085 = NEXT LINEhttps://www.fileformat.info/info/unicode/char/0085/index.htm

答案 2 :(得分:3)

整个过程都是一个正则表达式,因此您只需将其放入https://regexr.comhttps://regex101.com/中,它将为您提供正则表达式各部分含义的完整描述。

这是给你的:

  

(\ r \ n | [\ n \ r \ u2028 \ u2029 \ u0085])? / gm

     

第一个捕获组 (\ r \ n | [\ n \ r \ u2028 \ u2029 \ u0085])?

     

数量词-匹配0到1次,尽可能多地匹配,并根据需要返回(贪婪)

     

第一种选择 \ r \ n

     

\ r与回车符(ASCII 13)匹配

     

\ n与换行符(ASCII 10)匹配

     

第二种选择 [\ n \ r \ u2028 \ u2029 \ u0085]

     

匹配下面列表中出现的单个字符

     

[\ n \ r \ u2028 \ u2029 \ u0085]

     

\ n 与换行符(换行符)(ASCII 10)匹配

     

\ r 与回车符(ASCII 13)匹配

     

\ u2028 按字面意义(区分大小写)匹配具有索引202816(823210或200508)的字符      

\ u2029 按字面意义(区分大小写)匹配具有索引202916(823310或200518)的字符      

\ u0085 按字面意义(区分大小写)匹配索引为8516(13310或2058)的字符

     

全局模式标志

     

g修饰符: g 小叶。所有比赛(第一次比赛后不会返回)

     

m修饰符: m 多行。导致^和$匹配每行的开头/结尾(不仅是字符串的开头/结尾)

对于scanner.skip,这确实是(Scanner Pattern Tutorial):

  

java.util.Scanner.skip(Pattern pattern)方法将跳过与指定模式匹配的输入,而忽略分隔符。如果指定模式的锚定匹配成功,则此方法将跳过输入。如果在当前位置找不到与指定模式的匹配,则不跳过任何输入,并引发NoSuchElementException。

我还建议您在RegEx in Java: how to deal with newline上阅读Alan Moore's的答案,他谈论Java 1.8中的新方法。

答案 3 :(得分:1)

OpenJDK的源代码显示nextLine()将此正则表达式用于行分隔符:

private static final String LINE_SEPARATOR_PATTERN = "\r\n|[\n\r\u2028\u2029\u0085]";

答案 4 :(得分:1)

 scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
  1. 在Unix和所有类似Unix的系统中,\ n是行尾代码, \ r没什么特别的
  2. 因此,
  3. 在C语言和大多数以某种方式复制它的语言中(甚至 远程),\ n是行尾的标准转义序列 (根据需要转换为特定于OS的序列或从特定于OS的序列转换)
  4. 在旧的Mac系统(OS X之前的版本)中,\ r是行尾代码 相反,在Windows(和许多旧的操作系统)中,行尾的代码为2 字符\ r \ n,按此顺序(令人惊讶;-) (回到比Windows更早的操作系统),\ r \ n是标准配置 互联网上文​​本格式的行终止符
  

u0085下一行(NEL)

     

U2029参数分隔符

     

U2028线分隔符'

此操作背后的整个逻辑是,当输入来自扫描仪时,删除多余的空间和多余的新行

答案 5 :(得分:1)

scanner.skip此处已经存在类似的问题。它不会跳过空格,因为不存在Unicode字符(u0020)

\ r = CR(回车)//在Mac OS中用作X之前的换行符

\ n = LF(换行)//在Unix / Mac OS X中用作换行符

\ r \ n = CR + LF //在Windows中用作换行符

u2028 = line separator

u2029 = paragraph separator

u0085 = next line

答案 6 :(得分:1)

这会忽略一个line break, see \R

var obj = { selectProduct: function(e) { console.log($(this).text()); }, binds: function() { $('#sfProductList').on('click', '.lm-fancy-select__option', this.selectProduct); } } obj.binds();可以完全一样-感叹。

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sfProductList">
  <div class="lm-fancy-select__option">Foo</div>
  <div class="lm-fancy-select__option">Bar</div>
</div>

答案 7 :(得分:0)

我有一个简单得多的练习来解释这一点

  public class Solution {
    public static void main(String[] args) {
    int i = 4;
    double d = 4.0;
    String s = "HackerRank ";

    Scanner scan = new Scanner(System.in);

    int a;
    double b;
    String c = null;

    a = scan.nextInt();
    b = scan.nextDouble();
    c = scan.nextLine();

    System.out.println(c);
    scan.close();
    System.out.println(a + i);
    System.out.println(b + d);
    System.out.println(s.concat(c));
   }
}

尝试运行此文件。首先查看输出

之后

 public class Solution {

public static void main(String[] args) {
    int i = 4;
    double d = 4.0;
    String s = "HackerRank ";

    Scanner scan = new Scanner(System.in);

    int a;
    double b;
    String c = null;

    a = scan.nextInt();
    b = scan.nextDouble();
    scan.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
    c = scan.nextLine();

    System.out.println(c);
    scan.close();
    System.out.println(a + i);
    System.out.println(b + d);

    System.out.println(s.concat(c));
 }
}

再次尝试。

这可能是一个非常棘手的面试问题

在意识到这个问题之前,我一直在诅咒自己。

只要问任何程序员 取一个整数 取一个双数 和一个字符串 全部来自用户输入

如果他们不知道这一点,那么他们肯定会失败的。

您可以在其javadocs中找到有关整数和双精度形式的简单得多的答案

答案 8 :(得分:0)

它与扫描仪类别相关联:

让我们假设您从系统控制台输入了信息

4
This is next line

int a  =scanner.nextInt();
String s = scanner.nextLine();
a的

值将被读取为4 并且s的值将为空字符串,因为nextLine只会读取同一行中的next,然后移至nextLine


要完美阅读,您应该再添加一次nextLine(),如下所示

int a  =scanner.nextInt();
scanner.nextLine();
String s = scanner.nextLine();

以确保它到达下一行并在输入中存在任何异常时跳过所有内容

scan.skip("(\r\n|[\n\r\u2028\u2029\u0085])?"); 

上一行在每种操作系统和环境中都能完美运行。