Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个模式意味着什么?_Java - Fatal编程技术网

Java 这个模式意味着什么?

Java 这个模式意味着什么?,java,Java,我有一个自动化数据分析的脚本。不幸的是,我不知道输入数据文件的格式。我发现这段代码是为了在执行分析之前将文件的格式与某些先决条件相匹配。你能帮助理解这个模式的含义吗 private static final Pattern oldFileHeaderPattern = (newFileHeaderPattern = Pattern.compile("\\s*^\\s*(-1|0|1)\\s+(-1|0|1)\\s*$.*", 40)).compile("\\s*^\\s*(1|0)\\s*$.*

我有一个自动化数据分析的脚本。不幸的是,我不知道输入数据文件的格式。我发现这段代码是为了在执行分析之前将文件的格式与某些先决条件相匹配。你能帮助理解这个模式的含义吗

private static final Pattern oldFileHeaderPattern = (newFileHeaderPattern = Pattern.compile("\\s*^\\s*(-1|0|1)\\s+(-1|0|1)\\s*$.*", 40)).compile("\\s*^\\s*(1|0)\\s*$.*", 40)

这一行是如何不编写Java的主类。只有真正的大师才能把这么多的错误塞进一行

  • 我们可以在一行上初始化两个常量吗?不要那样做。永远不要那样做。这是一种静态方法。链接静态方法调用是愚蠢的

    private static final Pattern oldFileHeaderPattern = Pattern.compile("\\s*^\\s*(1|0)\\s*$.*", 40);
    private static final Pattern newFileHeaderPattern = Pattern.compile("\\s*^\\s*(-1|0|1)\\s+(-1|0|1)\\s*$.*", 40);
    
  • 硬编码这个神奇的数字
    40
    伤害了我的灵魂。如果需要多个标志,则应该将不同的命名常量合并在一起。不要写下号码

    private static final Pattern oldFileHeaderPattern = Pattern.compile("\\s*^\\s*(1|0)\\s*$.*", Pattern.DOTALL | Pattern.MULTILINE);
    private static final Pattern newFileHeaderPattern = Pattern.compile("\\s*^\\s*(-1|0|1)\\s+(-1|0|1)\\s*$.*", Pattern.DOTALL | Pattern.MULTILINE);
    
  • 现在我们来谈谈
    \\s*^
    $.*
    。在
    ^
    $
    锚定前后匹配内容是可疑的。通常你把这些放在正则表达式的开头和结尾,要求正则表达式匹配一个完整的行,你称之为一天

    使用
    *
    意味着它们可以匹配零个字符,因此它们实际上不会更改匹配的内容。让我们删除它们,只需使用
    ^
    $
    。这意味着我们也可以摆脱
    DOTALL
    ,因为
    已经不存在了

    private static final Pattern oldFileHeaderPattern = Pattern.compile("^\\s*(1|0)\\s*$", Pattern.MULTILINE);
    private static final Pattern newFileHeaderPattern = Pattern.compile("^\\s*(-1|0|1)\\s+(-1|0|1)\\s*$", Pattern.MULTILINE);
    

  • 正则表达式现在看起来不那么糟糕,是吗?第一个查找由
    1
    0
    组成的行,每侧都有可选的空格。第二个查找一行有两个数字,每个数字分别是
    -1
    0
    1

    ,虽然我没有答案,但这篇文章是一个很好的例子,说明了为什么尽可能避免使用正则表达式。如果您确实使用正则表达式,请将其做好文档记录,以便未来的开发人员不必询问StackOverflow正则表达式的含义。将其粘贴到正则表达式101中,它将对此进行解释。小心替身slashes@AndrewHill我觉得你的说法太笼统了。在某些情况下,正则表达式比30 loc的等价表达式更容易阅读。每个问题都有自己的特定工具。在Unix环境中,您每天都要处理正则表达式(这是关于思考,快和慢)。@steffen如果您要使用的正则表达式确实比其他正则表达式更简单,那么请尽一切努力实现它——只要确保您的代码易于将来需要维护它的人理解即可。对于那些想了解更多信息的人,我推荐这篇堆栈交换帖子:答案很好,但有一个小错误:
    ^
    由于多行,与“位于换行符或输入开始后的位置,但不在输入结束后”的概念相匹配。想象一个字符串,它以几行空白开始,然后是一个“1”,然后结束。如果在其上运行.matches(),它将失败,而使用
    \\s*^
    它将匹配。如果使用find(),这基本上无关紧要,但从原始粘贴中看这并不明显。$后面的.*与DOTALL组合表示,即使后面有许多行,.matches()也会匹配。这两个都很重要。似乎不太可能是为了在第一个模式之前允许空白行。鉴于代码的质量很差,我怀疑原始代码是否仔细地涵盖了所有边缘情况。最好使用新的正则表达式调用
    matcher(…).find()