#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