Разделить строки на третьем пробеле справа

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

strings <- c('abca eagh   ijkl mnop', 'dd1 ss j, ll bb aa')

Мне бы хотелось:

[1] 'abca', 'eagh   ijkl mnop' 
[2] 'dd1 ss j,', 'll bb aa'

Ближайшее, что я смог найти, это:

strsplit(strings, split = "(?<=\\S)(?=\\s(.*)\\s(.*)\\s(.*)$)", perl = TRUE)

который возвращает:

[[1]]
[1] "abca"         " eagh"        "   ijkl mnop"

[[2]]
[1] "dd1"       " ss"       " j,"       " ll bb aa"

Я все думаю, что ответ должен быть примерно таким:

strsplit(strings, split = "(?<=\\S\\s(.*)\\s(.*)\\s(.*)$)(?=\\s(.*)\\s(.*)\\s(.*)$)", perl = TRUE)

Однако это возвращает ошибку. Спасибо за любой совет. Я предпочитаю базовое решение, надеюсь, такое, которое использует регулярные выражения.


person Mark Miller    schedule 20.02.2014    source источник
comment
Можете ли вы перевернуть строку, затем разделить перевернутую строку на третье белое пространство слева (это может быть проще!), А затем перевернуть каждую подстроку?   -  person Theox    schedule 20.02.2014
comment
Разве первый пример abca eagh{SPACE}{SPACE}{SPACE}ijkl{SPACE}mnop не должен давать вам 'abca eagh',' ijkl mnop' в зависимости от ваших требований?   -  person JonM    schedule 20.02.2014
comment
@JonM Возможно, я неправильно использую термин «пустое пространство». Прости за это. Я включил строки и желаемые результаты.   -  person Mark Miller    schedule 20.02.2014
comment
Итак, следует ли рассматривать последовательные пробелы как «один» пробел (например, 5 пробелов в строке должны считаться одним пробелом)?   -  person JonM    schedule 20.02.2014
comment
Да, 5 последовательных пробелов рассматриваются как один пробел.   -  person Mark Miller    schedule 20.02.2014


Ответы (2)


Попробуйте выражение:

(?=(?>\\s\\S*){3}$)\\s

Изменить: используйте это выражение, если хотите, чтобы последовательные символы пробелов обрабатывались как «один» пробел:

(?=(?>\\s+\\S*){3}$)\\s

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

Понятно! Извините, я не на 100% понял, как работает функция strsplit. Попробуй это:

strsplit(strings, split = "(?=(?>\\s+\\S*){3}$)\\s", perl = TRUE)

Вот пример вывода:

> strings <- c('abca eagh   ijkl mnop', 'dd1 ss j, ll bb aa')
> strsplit(strings, split = "(?=(?>\\s+\\S*){3}$)\\s", perl = TRUE)
[[1]]
[1] "abca"             "eagh   ijkl mnop"

[[2]]
[1] "dd1 ss j," "ll bb aa" 
person JonM    schedule 20.02.2014
comment
Я получаю ошибки с обоими. Я использую R. Одна ошибка связана с \ как escape-символом. Использование \\ не устраняет всех ошибок. - person Mark Miller; 20.02.2014
comment
Хорошо, я обновил ответ. Я дал ему синтаксис, специфичный для R. - person JonM; 20.02.2014
comment
Ты прав! Я обновил свой ответ! Я был неправ, потому что говорил функции strsplit разбивать всю строку! - person JonM; 20.02.2014

Как насчет использования следующего регулярного выражения: (\S*\s*\S*\s*\S*\s*)(.*)? См. http://regex101.com/r/lI7aA9

person Uri Y    schedule 20.02.2014
comment
Это возвращает ошибки. Я использую R, который, кажется, предпочитает \\ над \. Однако после использования \\. - person Mark Miller; 20.02.2014