2015-03-25 5 views
3

Я пытаюсь разбить строку только на группу захвата регулярного выражения, но я, кажется, раскалываюсь во всем матче.scala split on capture group

Я хотел бы разделить hi|my~~|~|name is bob на | «с которым предшествует ноль или любого четного числа ~» s

Так что мой ожидается выход Array(hi, my~~, ~|name is bob)

Я использую регулярное выражение "(?<!~)(?:~~)*(\\|)"

Но "hi|my~~|~|name is bob".split("(?<!~)(?:~~)*(\\|)") возвращает Array[String] = Array(hi, my, ~|name is bob), потому что он делится на весь ~~| после my, а не только |, который преследует ed by ~~.

Например сравнения:

scala> "(?<!~)(?:~~)*(\\|)".r.findAllIn("hi|my~~|~|name is bob").foreach(println) 
| 
~~| 

в

scala> "(?<!~)(?:~~)*(\\|)".r.findAllIn("hi|my~~|~|name is bob").matchData foreach { m => println(m.group(1)) } 
| 
| 

EDIT:

Некоторые контекст и уточнение:

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

Для достижения желаемой функциональности я хочу избежать всех вхождений |. Я выбрал ~ в качестве моего escape-символа. Прежде чем я смогу убежать | Мне нужно бежать ~.

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

Затем, чтобы разобрать одну строку обратно в исходный список, мне нужно разделить только на unescaped |. Я должен быть осторожен, потому что что-то вроде ~~| на самом деле представляет собой неизолированную трубу, хотя она содержит ~|. Это происходит потому, что escape-символ сам экранирован, а это означает, что это только «тильда» в одной из моих исходных строк и не предназначено для функции «побега». Другими словами, у меня была строка, заканчивающаяся на ~, и теперь она сбежала в ~~ и присоединилась к следующей строке в списке с помощью '|'.

ОК, поэтому, если мой первоначальный список строк ["hi","my~","|name is bob"] Я сбегу от всех ~, чтобы получить ["hi","my~~","|name is bob"]. Теперь я избежать всех | «с, чтобы получить ["hi","my~~","~|name is bob"], и, наконец, я присоединюсь с |, чтобы получить одну строку:

" hi|my~~|~|name is bob"

Теперь, если я хочу изменить это мне нужно сначала раскол на неэкранированном | , которое равно |, которому предшествует нуль или четное число ~.Поэтому, если я могу добиться этого с помощью своего регулярного выражения (до сих пор я правильно его фиксирую в своей группе захвата, но я просто не знаю, как применять только группу, а не полный ~~|, например, к расколу), тогда я получит ["hi","my~~","~|name is bob"]. Теперь я просто экранирование в моем ~ «с, экранированием в моих |, и я вернулся в моем первоначальном входе:

["hi","my~","|name is bob"]

+0

Я не понимаю, ожидаемый результат: Array (привет, мой ~~, ~ | имя боб). Почему сепараторы являются частью этого? Почему не Массив (привет, мой, имя боб)? – Attilio

+0

The | в моем ожидаемом выходе не является разделителем. Это | это было в моем первоначальном входе, и этого нужно было избежать, поэтому я не путал его с разделителем. Пожалуйста, см. Мое редактирование для получения дополнительных разъяснений. – Imran

ответ

3

Вам нужно все ~ s, чтобы быть частью взгляда-за группой, так как split разделяет на целое совпадение регулярного выражения, а не только его группы, даже если эта группа не является группой для захвата. Более простой пример:

"asdf" split "(?:s)" //Array(a, df) 

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

"""(?<=(?<!~)(~~)*)\|""" 

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

"""(?<=(?<!~)(~~){0,10})\|""" 

, которая будет работать для четного числа ~ с тех пор, как 20 или меньше. Вы можете увеличить 10, если это проблема.

Если вложенные просмотровых задом запутаны, вы можете также использовать эквивалент:

"""(?<![^~]~(~~){0,10})\|""" 
+0

'' hi | my ~~ | ~ | name is bob "split" "" (? <= (~~) {0,10}) \ | "" "' дает 'Array (hi, my ~~, ~ , name - bob) 'not' Array (hi, my ~~, ~ | name is bob) '. –

+1

Очень хороший ответ. Спасибо, что нашли время, чтобы получить эту работу. – Imran