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

#java #regex

#java #регулярное выражение

Вопрос:

Я новичок в регулярных выражениях на Java, и я хотел бы знать, как я могу создать такое выражение, которое принимает только строку, состоящую из одного или двух списков прописных букв, разделенных запятыми, разделенных одним пробелом.

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

Все это было бы недопустимо:

  • "D,, D"
  • "D D,,"
  • "D, ,D"
  • "D, ,,D"
  • "D,, ,D"
  • "D,,"
  • ",,A"
  • ",A"
  • "A,"

Все это было бы допустимо:

  • "D,D T,F"
  • "D,D T"
  • "A,A"
  • "A"

Я использовал (s?("[ws]*"|d*)s?(,,|$)) для последовательных запятых, но это не помогает, когда запятая находится в конце или начале одной из подстрок, разделенных пробелами, например "D, ,D"

Должен ли я стремиться к разделению на пробелы и искать более простое регулярное выражение для каждой из подстрок?

Комментарии:

1. отклонить, если это ^s*,|,s*,|,s*$ найдено , нажмите Java для проверки // или split(",", -1) и проверьте, является ли какая-либо запись пустой (только пробелы)

2. Да, это допустимо. Это будет квалифицироваться как список, разделенный одной запятой, что вполне нормально.

Ответ №1:

Это было бы что-то вроде этого:

 ^[A-Z](,[A-Z])*( [A-Z](,[A-Z])*)*$
 

Здесь происходит следующее:

  • Мы ожидаем, что за буквой, необязательно, следует один или несколько раз запятая, за которой сразу следует другая буква.
  • Затем мы необязательно принимаем пробел, а затем вышеупомянутый шаблон. И это повторяется.

Тест: https://regex101.com/r/kzLhtw/1

Вы могли бы, конечно, немного оптимизировать регулярное выражение, сделав все группы захвата не захватываемыми: просто поместите ?: сразу за ( , то есть (?: .

Комментарии:

1. @JvdV Спасибо, но я думаю, что запись D T действительно совпадает. Я обновил ссылку на regex101, чтобы включить тестовый пример.

2. Верно, я виноват. Я был слишком быстр там =). Имейте в виду, что вы допускаете несколько пробелов! Я заметил это и с другим ответом. Может быть, мой разум сегодня не там, но, похоже, OP ищет один или два списка, разделенных запятыми. В случае двух списков два списка разделяются пробелом. В любом случае, у вас уже был мой голос.

Ответ №2:

Вы можете использовать

 ^[A-Z](?: [A-Z])*(?:,[A-Z](?: [A-Z])*){0,2}$
 
  • ^ Начало строки
  • [A-Z] Сопоставление одного символа от А доЯ
  • (?: [A-Z])* При необходимости повторите пробел и один символ Az
  • (?: Не группа захвата
    • ,[A-Z](?: [A-Z])* Сопоставьте запятую, символ A-Z, за которым при необходимости повторите сопоставление пробела и символа A-Z
  • ){0,2} Закройте группу и повторите 0-2 раза
  • $ Конец строки

Демонстрация регулярных выражений

Комментарии:

1. Заголовок @TheFourthBird. Это также будет соответствовать строкам с несколькими пробелами. Обратите внимание, может быть один или два списка, разделенных запятыми. Эти списки разделяются пробелом. =). Подумал, что было бы неплохо сообщить вам об этом.

2. @JvdV Я читал это как одну или две запятые, где символы верхнего регистра разделены пробелом.

Ответ №3:

«строка, состоящая из одного или двух списков заглавных букв, разделенных запятыми, разделенных одним пробелом»

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

Вы могли бы попробовать:

 ^(?!.* .* )[A-Z](?:[ ,][A-Z])*$
 

Смотрите онлайн-демонстрацию

  • ^ — Начать привязку строки.
  • (?!.* .* ) — Отрицательный прогноз для предотвращения присутствия двух пробелов.
  • [A-Z] — Один прописной буквенный символ.
  • (?: — Открыть группу без захвата:
    • [ ,] — Запятая или пробел.
    • [A-Z] — Один прописной буквенный символ.
    • )* — Закрыть группу без захвата и сопоставить 0 раз до;
  • $ — Конец привязки строки.

Комментарии:

1.(Я уже проголосовал, я думаю, что это привело бы к меньшему возврату :-)) ^(?!S S )[A-Z](?:[ ,][A-Z])*$ regex101.com/r/9EXiga/1