2016-09-27 4 views
3

У меня есть следующая строка:Разбивает строку пробелами, за исключением того, что внутри скобок

x <- "(((K05708+K05709+K05710+K00529) K05711),K05712) K05713 K05714 K02554" 
# [1] "(((K05708+K05709+K05710+K00529) K05711),K05712) K05713 K05714 K02554" 

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

[[1]] 
[1] "(((K05708+K05709+K05710 K00529) K05711),K05712)"     
[2] "K05713"       "K05714"       
[4] "K02554" 

Посмотрите, что в первом круглом скобке осталось два пробела.

Я прочитал следующие ответы, но я не мог заставить его работать в моем случае: r split on delimiter not in parentheses и Using strsplit() in R, ignoring anything in parentheses

Спасибо заранее!

+0

Похоже, ваша строка имеет вложенные сбалансирован '()', и вам необходимо, чтобы пропустить эти пробелы внутри * уравновешенных * скобки, верно? –

+0

Да! Ты прав. – IgnacioF

+0

Содержит ли последняя скобка на каждой строке конец первого поля? Известно ли количество полей (здесь 4)? –

ответ

3

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

(\((?:[^()]++|(?1))*\))(*SKIP)(*F)|\s 

Смотрите regex demo (заменить пространство \s выше для лучшей видимости). Подробнее

шаблон:

  • (\((?:[^()]++|(?1))*\))(*SKIP)(*F) - Группа 1 соответствие
    • \((?:[^()]++|(?1))*\) - подстрока представления сбалансированной скобок подстроки: \( соответствует (, (?:[^()]++|(?1))* соответствует нулю или более (*) последовательностей 1+, кроме ( и ) (см. [^()]++) или весь шаблон всей этой Группы 1 (см subrouting вызов (?1)), то \) соответствует буквальному ) и (*SKIP)(*F) сделать регулярное выражение отбрасывать весь совпавший текст с, сохраняя при этом индекса регулярных выражений в конце этого матча, и продолжить искать следующий матч
  • | - или
  • - пространство для разделения против

Вот это online R demo:

s <- "(((K05708+K05709+K05710+K00529) K05711),K05712) K05713 K05714 K02554" 
strsplit(s, "(\\((?:[^()]++|(?1))*\\))(*SKIP)(*F)| ", perl=TRUE) 

Выход:

[[1]] 
[1] "(((K05708+K05709+K05710+K00529) K05711),K05712)" 
[2] "K05713"           
[3] "K05714"           
[4] "K02554" 
+0

Спасибо! Кажется, он работает нормально. Не могли бы вы немного объяснить регулярное выражение, которое вы использовали? – IgnacioF

+0

Пожалуйста, проверьте мой ответ. Если объяснений недостаточно, см. Также [Реджикс Рекурсия] (http://www.regular-expressions.info/recurse.html) и [Подпрограммы] (http://www.regular-expressions.info/subroutine.html). Кроме того, см. [Как (* SKIP) или (* F) работать с регулярным выражением?] (Http://stackoverflow.com/questions/24534782/how-do-skip-or-f-work-on-regex). –

Смежные вопросы