Регулярное выражение для обработки двух разных расширений файлов - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь создать регулярное выражение, которое принимает файл с именем «abcd_04-04-2020.txt» или «abcd_04-04-2020.txt.gz»

Как я могу обработать " ИЛИ "условие продления. Это то, что у меня есть

if(fileName.matches("([\\w._-]+[0-9]{2}-[0-9]{2}-[0-9]{4}.[a-zA-Z]{3})")){
    Pattern.compile("[._]+[0-9]{2}-[0-9]{2}-[0-9]{4}\\.");
}

Это обрабатывает только .txt. Как я могу обрабатывать ".txt.gz" Спасибо

Ответы [ 6 ]

2 голосов
/ 29 мая 2020

Вы можете использовать следующее регулярное выражение для достижения своей цели:

^[\w-]+\d{2}-\d{2}-\d{4}\.txt(?:\.gz)?$

Объяснение приведенного выше регулярного выражения: ]

^,$ - соответствует началу и концу тестовой строки, соответственно.

[\w-]+ - один или несколько раз соответствует символу слова и дефису.

\d{} - соответствует количеству цифр, указанному в фигурных скобках.

(?:\.gz)? - представляет собой сопоставление групп без захвата .gz ноль или один раз из-за? квантификатор . Вы могли бы использовать чередование | (или, как вы ожидали, ИЛИ ), но это также разборчиво и более эффективно.

Вы можете найти демонстрацию вышеуказанного регулярного выражения здесь.

Regular expression visualization

IMPLEMENTATION IN JAVA:

import java.util.regex.*;
public class Main
{
    private static final Pattern pattern = Pattern.compile("^[\\w-]+\\d{2}-\\d{2}-\\d{4}\\.txt(?:\\.gz)?$", Pattern.MULTILINE);
    public static void main(String[] args) {
        String testString = "abcd_04-04-2020.txt\nabcd_04-04-2020.txt.gz\nsomethibsnfkns_05-06-2020.txt\n.txt.gz";
        Matcher matcher = pattern.matcher(testString);
        while(matcher.find()){
            System.out.println(matcher.group(0));
        }
    }
}

You can find the implementation of the above regex in java in здесь.

ПРИМЕЧАНИЕ: Если хотите также соответствовать действительным датам; пожалуйста, посетите здесь.

2 голосов
/ 29 мая 2020

? будет работать на ваш необходимый | . Попробуйте добавить

(.[a-zA-Z]{2})?

в исходное регулярное выражение

([\w._-]+[0-9]{2}-[0-9]{2}-[0-9]{4}.[a-zA-Z]{3}(.[a-zA-Z]{2})?)
2 голосов
/ 29 мая 2020

Почему бы просто не использовать endsWith вместо сложного регулярного выражения

if(fileName.endsWith(".txt") || fileName.endsWith(".txt.gz")){
 Pattern.compile("[._]+[0-9]{2}-[0-9]{2}-[0-9]{4}\\.");
}
1 голос
/ 29 мая 2020

Возможный способ сделать это:

Pattern pattern = Pattern.compile("^[\\w._-]+_\\d{2}-\\d{2}-\\d{4}(\\.txt(\\.gz)?)$");

Затем вы можете запустить следующий тест:

String[] fileNames = {
        "abcd_04-04-2020.txt",
        "abcd_04-04-2020.tar",
        "abcd_04-04-2020.txt.gz",
        "abcd_04-04-2020.png",
        ".txt",
        ".txt.gz",
        "04-04-2020.txt"
};

Arrays.stream(fileNames)
        .filter(fileName -> pattern.matcher(fileName).find())
        .forEach(System.out::println);

// output
// abcd_04-04-2020.txt
// abcd_04-04-2020.txt.gz
1 голос
/ 29 мая 2020

Вы можете заменить .[a-zA-Z]{3} на .txt(\.gz)

if(fileName.matches("([\\w._-]+[0-9]{2}-[0-9]{2}-[0-9]{4}).txt(\.gz)?")){
   Pattern.compile("[._]+[0-9]{2}-[0-9]{2}-[0-9]{4}\\.");
}
1 голос
/ 29 мая 2020

Я думаю, что вы хотите (следуя направлению, в котором вы двигались), это:

[\\w._-]+[0-9]{2}-[0-9]{2}-[0-9]{4}\\.[a-zA-Z]{3}(?:$|\\.[a-zA-Z]{2}$)

В конце концов, у меня есть условное выражение. Он должен либо соответствовать концу строки ($), либо соответствовать буквальной точке, за которой следуют 2 буквы (\\.[a-zA-Z]{2}). Не забудьте экранировать ., потому что в регулярном выражении . означает «соответствовать любому символу».

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