Что означает этот шаблон? - PullRequest
3 голосов
/ 06 июля 2019

У меня есть скрипт для автоматизации анализа данных. К сожалению, я не знаю формат файла входных данных. Я нашел этот фрагмент кода, который предназначен для соответствия формата файла определенным предварительным условиям перед выполнением анализа. Можете ли вы помочь понять, что означает шаблон?

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)

1 Ответ

7 голосов
/ 06 июля 2019

Эта строка является мастер-классом о том, как не писать Java.Только настоящий мастер может собрать столько ошибок в одну строку.

  1. Можем ли мы говорить об инициализации двух констант в одной строке?Не делай этого.Никогда не делай этого.Pattern.compile() - статический метод.Цепные статические вызовы методов - это безумие.

    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);
    
  2. Жесткое кодирование магического числа 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);
    
  3. Теперь поговорим о \\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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...