Регулярные выражения и множественные многосимвольные разделители - PullRequest
1 голос
/ 19 сентября 2008

Предположим, у вас есть следующая строка:

white sand, tall waves, warm sun

Легко написать регулярное выражение, которое будет соответствовать разделителям, которые метод Java String.split () может использовать для получения массива, содержащего токены "белый песок", "высокие волны" и "теплое солнце":

\s*,\s*

Теперь скажите, что у вас есть эта строка:

white sand and tall waves and warm sun

Опять же, регулярное выражение для разделения токенов легко (если вы не получите "и" внутри слова "песок"):

\s+and\s+

Теперь рассмотрим эту строку:

white sand, tall waves and warm sun

Можно ли написать регулярное выражение, которое будет правильно соответствовать разделителям, что позволит вам разбить строку на те же токены, что и в предыдущих двух случаях? Кроме того, можно ли написать регулярное выражение, которое будет соответствовать самим токенам и опускать разделители? (Любое количество пробелов по обе стороны от запятой или слова «и» следует считать частью разделителя.)

Редактировать: Как было указано в комментариях, правильный ответ должен надежно обрабатывать разделители в начале или конце входной строки. идеальный ответ должен быть в состоянии взять строку типа «белый песок, высокие волны и теплое солнце и» и предоставить три точных жетона:

[ "white sand", "tall waves", "warm sun" ]

... без дополнительных пустых токенов или дополнительных пробелов в начале или конце любого токена.

Edit: было отмечено, что дополнительные пустые токены неизбежны с String.split (), поэтому он был удален как критерий для "идеального" регулярного выражения.


Спасибо всем за ваши ответы! Я пытался убедиться, что проголосовал за каждого, кто внес работоспособное регулярное выражение, которое по сути не было дубликатом. Ответ Дэна был самым надежным (он даже обрабатывает ", белый песок, высокие волны и теплое солнце и" разумно, с этим странным запятым после слова "волны"), поэтому я отметил его как принятый ответ. Регулярное выражение, предоставленное nsayer, было второй секундой.

Ответы [ 7 ]

5 голосов
/ 19 сентября 2008

Это должно быть довольно гибким, и обрабатывать такие вещи, как разделители в конце строки (например, "foo and bar and")

\s*(?:\band\b|,)\s*
2 голосов
/ 19 сентября 2008

Будет ли это работать?

\s*(,|\s+and)\s+
2 голосов
/ 19 сентября 2008

проблема с

\s*(,|(and))\s*

состоит в том, что он неуместно разделит «песок».

Проблема с

\s+(,|(and))\s+

означает, что для этого требуются пробелы вокруг запятых.

Правильный ответ, вероятно, должен быть

(\s*,\s*)|(\s+and\s+)

Я немного обманываю концепцию возврата строк, окруженных разделителями, предполагая, что во многих языках есть оператор «split», который делает именно то, что вы хотите, когда регулярное выражение определяет форму самого разделителя. См. Функцию Java String.split ().

2 голосов
/ 19 сентября 2008

Это должно поймать и 'и' или ','

(?:\sand|,)\s
1 голос
/ 19 сентября 2008

Да, это то, что регулярное выражение для:

\s*(?:and|,)\s*

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

РЕДАКТИРОВАТЬ: чтобы избежать песчаной ловушки (спасибо за уведомление):

\s*(?:[^s]and|,)\s*
0 голосов
/ 19 сентября 2008

Может быть:

((\ S * \ S *) | (\ s + и \ S +))

Я не программист Java, поэтому я не уверен, позволяет ли Java-регулярное выражение '?'

0 голосов
/ 19 сентября 2008
(?:(?<!s)and\s+|\,\s+)

Мог бы работать

Не могу проверить это, но достал только космическое сопоставление.

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