Java регулярное выражение для фильтрации файлов

Я хотел бы построить регулярное выражение в Java, которое будет передано в FilenameFilter для фильтрации файлов в каталоге.

Проблема в том, что я не могу освоить регулярные выражения "модели ума" :)

Это регулярное выражение, которое я придумал, чтобы выбрать файлы, которые я хотел бы исключить

((ABC | XYZ)) + \ ш * test.xml

Я хотел бы выбрать все файлы, которые заканчиваются на Test.xml, но не начинаются с ABC или XYZ.

Не могли бы вы добавить любые ресурсы, которые могут помочь мне в моей битве с регулярными выражениями.

Спасибо

Следующий ресурс объясняет многое о регулярных выражениях regular-expressions.info

15.12.2008 09:32:52
5 ОТВЕТОВ
РЕШЕНИЕ

Я хотел бы выбрать все файлы, которые заканчиваются, Test.xml но не начинаются с ABCили XYZ.

Либо вы сопоставляете все свои файлы с этим регулярным выражением:

^(?:(?:...)(?<!ABC|XYZ).*?)?Test\.xml$

или вы делаете противоположное, и берете каждый файл, который не соответствует:

^(?:ABC|XYZ).*?Test\.xml$

Лично я нахожу второй вариант намного проще.

ABC_foo_Test.xml // # 2 совпадения
XYZ_foo_Test.xml // # 2 совпадения
ABCTest.xml // # 2 совпадения 
XYZTest.xml // # 2 совпадения
DEF_foo_Test.xml // # 1 совпадений
DEFTest.xml // # 1 совпадений
Test.xml // # 1 совпадений
4
15.12.2008 10:10:46

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

if (str.endsWith("Test.xml") && !str.startsWith("ABC"))
9
15.12.2008 09:38:43

Просто для удовольствия от регулярного выражения:

(?ms)^([^\r\n]{3}(?<!ABC|XYZ)[^\r\n]*?)?Test\.xml$

Даже если это не самое удобочитаемое решение, оно должно работать, и вам не придется определять собственный фильтр файлов.

(?<!ABC|XYZ) является условным выражением, избегающим любого четвертого символа (после первых трех символов) перед тем, чего вы хотите избежать.

1
15.12.2008 11:16:28
@ Томалак: Спасибо, я только что исправил свое регулярное выражение и +1 к вашему (хотя я предпочитаю [\ r \ n] «.».
VonC 15.12.2008 11:17:46
Но в этом случае: имена файлов не могут содержать разрывы строк. Кроме того, в обычном режиме точка не соответствует символам новой строки, поэтому использование [^ \ r \ n] кажется мне излишним.
Tomalak 15.12.2008 12:20:28
Согласовано. У меня просто был плохой предыдущий опыт с '.' раньше (предполагая, что в моих записях не будет новой строки). Таким образом, я избегаю каких-либо сюрпризов.
VonC 15.12.2008 12:34:07
Использую ли я ".", "[^ \ R \ n]" или однострочный режим, зависит от ситуации, я не обобщаю здесь. Но всегда быть явным - тоже хорошо. :) Я думаю, суть в том, что регулярное выражение действительно плохо сопоставляет «все, кроме того или другого». Позитивное сопоставление легче осуществить в любом случае.
Tomalak 15.12.2008 12:53:46

Это выберет файлы, которые не начинаются с A, B, C, X, Y или Z и заканчиваются в Test.xml:

"[^ ABCXYZ]. * Тест \\. \\ г XML"

  • [^ ABCXYZ]: любой символ, не входящий в набор A, B, C, X, Y, Z.
  • . *: Любой символ, ноль или более раз
  • Тест: точный текст "Тест"
  • \\ .: Точечный символ (необходимо экранировать с помощью обратной косой черты, а если вы находитесь в строке, то эту обратную косую черту нужно экранировать ... обратной косой чертой!)
  • xml: точный текст "xml"
  • \\ z: конец ввода
0
15.12.2008 14:03:32
Боюсь, это был не вопрос. Это не соответствует «ACD_Test.xml», хотя это должно произойти, и двойные обратные слеши неправильны для регулярных выражений, они являются требованием языка программирования.
Tomalak 15.12.2008 14:56:57
ОП действительно сказал, что это регулярное выражение Java, а в строковых литералах Java обратные слэши в escape-последовательностях регулярных выражений должны быть удвоены. Тем не менее, отрицательный класс символов в начале определенно ошибочен.
Alan Moore 15.12.2008 20:23:56

Регулярные выражения, предоставляемые Tomalak и VonC, более сложны, чем они должны быть. Поместить отрицательный взгляд в начало регулярного выражения гораздо яснее, чем сопоставить три символа и сделать отрицательный взгляд позади. И если вы используете matches()метод, вы не должны даже использовать якоря ( ^, $, \z).

public boolean accept(File dir, String name) {
    return name.matches("(?!ABC|XYZ).*Test\\.xml");
}
1
15.12.2008 20:49:13