Удалить текст внутри скобок, скобок и / или фигурных скобок - PullRequest
8 голосов
/ 24 декабря 2011

Мне нужна функция, которая извлекает скобки любого типа, например (), [], {} и информацию между ними.Я создал его и заставил делать то, что хочу, но получаю досадное предупреждение о том, что на самом деле не знаю, что это значит.Я хочу, чтобы раздражающее предупреждение исчезло, либо исправляя ошибки в моем коде, либо подавляя предупреждение.Я попытался сделать это с помощью suppressWarnings (), но это не сработало, потому что я не думаю, что использовал его правильно.

Эта функция использует соответствия и требует R версии 2.14 или выше

Вот функцияниже и пример для воспроизведения предупреждения.Спасибо за помощь.

################
# THE FUNCTION #
################
bracketXtract <- function(text, bracket = "all", include.bracket = TRUE) {

    bracketExtract <- if (include.bracket == FALSE) {
        function(Text, bracket) {
                  switch(bracket, 
                        square = lapply(Text, function(j) gsub("[\\[\\]]", "", 
                                 regmatches(j, gregexpr("\\[.*?\\]", j))[[1]], 
                                 perl = TRUE)), 
                        round =  lapply(Text, function(j) gsub("[\\(\\)]", "", 
                                 regmatches(j, gregexpr("\\(.*?\\)", j))[[1]])), 
                        curly =  lapply(Text, function(j) gsub("[\\{\\}]", "", 
                                 regmatches(j, gregexpr("\\{.*?\\}", j))[[1]])), 
                        all =    { P1 <- lapply(Text, function(j) gsub("[\\[\\]]", "", 
                                         regmatches(j, gregexpr("\\[.*?\\]", j))[[1]], 
                                         perl = TRUE))
                                   P2 <- lapply(Text, function(j) gsub("[\\(\\)]", "", 
                                         regmatches(j, gregexpr("\\(.*?\\)", j))[[1]]))
                                   P3 <- lapply(Text, function(j) gsub("[\\{\\}]", "", 
                                         regmatches(j, gregexpr("\\{.*?\\}", j))[[1]]))
                    apply(cbind(P1, P2, P3), 1, function(x) rbind(as.vector(unlist(x))))
                })
        }
    } else {
        function(Text, bracket) {
                  switch(bracket, 
                         square = lapply(Text, function(j) regmatches(j, 
                                  gregexpr("\\[.*?\\]", j))[[1]]), 
                         round =  lapply(Text, function(j) regmatches(j, 
                                  gregexpr("\\(.*?\\)", j))[[1]]), 
                         curly =  lapply(Text, function(j) regmatches(j, 
                                  gregexpr("\\{.*?\\}", j))[[1]]), 
                         all =    { P1 <- lapply(Text, function(j) regmatches(j, 
                                          gregexpr("\\[.*?\\]", j))[[1]])
                                    P2 <- lapply(Text, function(j) regmatches(j, 
                                          gregexpr("\\(.*?\\)", j))[[1]])
                                    P3 <- lapply(Text, function(j) regmatches(j, 
                                          gregexpr("\\{.*?\\}", j))[[1]])
                apply(cbind(P1, P2, P3), 1, function(x) rbind(as.vector(unlist(x))))
            })
        }
    }
    if (length(text) == 1) {
        unlist(lapply(text, function(x) bracketExtract(Text = text,
            bracket = bracket)))
    } else {
        sapply(text, function(x) bracketExtract(Text = text, 
            bracket = bracket))
    }
} 

##################
# TESTING IT OUT #
##################
j <- "What kind of cheese isn't your cheese? {wonder} Nacho cheese! [groan] (Laugh)"                                                          
bracketXtract(j, 'round')
bracketXtract(j, 'round', include.bracket = FALSE)

examp2<-data.frame(var1=1:4)                                                                                                                               
examp2$text<-as.character(c("I love chicken [unintelligible]!", "Me too! (laughter) It's so good.[interupting]", 
             "Yep it's awesome {reading}.", "Agreed."))

#=================================#
# HERE"S WHERE THE WARNINGS COME: #
#=================================#                                                                                                                                                            
examp2$text2<-bracketXtract(examp2$text, 'round')                                                                                                  
   examp2
examp2$text2<-bracketXtract(examp2$text, 'all')                                                                                                  
   examp2

Ответы [ 4 ]

7 голосов
/ 24 декабря 2011

Может быть, эта функция немного более проста? Или хотя бы более компактный.

bracketXtract <-
    function(txt, br = c("(", "[", "{", "all"), with=FALSE)
{
    br <- match.arg(br)
    left <-        # what pattern are we looking for on the left?
        if ("all" == br) "\\(|\\{|\\["
        else sprintf("\\%s", br)
    map <-         # what's the corresponding pattern on the right?
        c(`\\(`="\\)", `\\[`="\\]", `\\{`="\\}",
          `\\(|\\{|\\[`="\\)|\\}|\\]")
    fmt <-         # create the appropriate regular expression
        if (with) "(%s).*?(%s)"
        else "(?<=%s).*?(?=%s)"
    re <- sprintf(fmt, left, map[left])
    regmatches(txt, gregexpr(re, txt, perl=TRUE))    # do it!
}

Не нужно lapply; функции регулярного выражения векторизованы таким образом. Это терпит неудачу с вложенными скобками; скорее всего, регулярные выражения не будут хорошим решением, если это важно. Вот мы в действии:

> txt <- c("I love chicken [unintelligible]!",
+          "Me too! (laughter) It's so good.[interupting]",
+          "Yep it's awesome {reading}.",
+          "Agreed.")
> bracketXtract(txt, "all")
[[1]]
[1] "unintelligible"

[[2]]
[1] "laughter"    "interupting"

[[3]]
[1] "reading"

[[4]]
character(0)

Это без проблем вписывается в data.frame.

> examp2 <- data.frame(var1=1:4)
> examp2$text <- c("I love chicken [unintelligible]!",
+                  "Me too! (laughter) It's so good.[interupting]",
+                  "Yep it's awesome {reading}.", "Agreed.")
> examp2$text2<-bracketXtract(examp2$text, 'all')
> examp2
  var1                                          text                 text2
1    1              I love chicken [unintelligible]!        unintelligible
2    2 Me too! (laughter) It's so good.[interupting] laughter, interupting
3    3                   Yep it's awesome {reading}.               reading
4    4                                       Agreed.                      

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

> df = data.frame(x=1:2)
> df$y = matrix(list(), 2, 2)
> df
  x    y
1 1 NULL
2 2 NULL
Warning message:
In format.data.frame(x, digits = digits, na.encode = FALSE) :
  corrupt data frame: columns will be truncated or padded with NAs
4 голосов
/ 24 декабря 2011

Я думал о том, чтобы сделать 6 (неявно векторизованных) вспомогательных функций, но вместо этого я буду изучать код Мартина, поскольку он намного лучше в этом, чем я:

rm.curlybkt.no <-function(x) gsub("(\\{).*(\\})", "\\1\\2", x, perl=TRUE)
rm.rndbkt.no <-  function(x) gsub("(\\().*(\\))", "\\1\\2", x, perl=TRUE)
rm.sqrbkt.no <-  function(x) gsub("(\\[).*(\\])", "\\1\\2", x, perl=TRUE)

rm.rndbkt.in <- function(x) gsub("\\(.*\\)", "", x)
rm.curlybkt.in <- function(x) gsub("\\{.*\\}", "", x)
rm.sqrbkt.in   <- function(x) gsub("\\[.*\\]", "", x)
3 голосов
/ 24 декабря 2011

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

x <- c("a (bb) [ccc]{d}e", "x[a]y")

Затем, используя strapply в gsubfn, мы имеем это двухстрочное решение, которое сначала переводит все скобки и квадратные скобки в скобкив скобках и затем обрабатывает это:

library(gsubfn)    

xx <- chartr("[]()", "{}{}", x)
s <- strapply(xx, "{([^}]*)}", c)

Результатом вышеизложенного является следующий список:

> s
[[1]]
[1] "bb"  "ccc" "d"  

[[2]]
[1] "a"
0 голосов
/ 29 июля 2014

Дайте этому шанс. Я предпочитаю пакет stringr! :)

bracketXtract <- function(string, bracket = "all", include.bracket = TRUE){
  # Load stringr package
  require(stringr)

  # Regular expressions for your brackets
  rgx = list(square = "\\[\\w*\\]", curly  = "\\{\\w*\\}", round  = "\\(\\w*\\)")
  rgx['all'] = sprintf('(%s)|(%s)|(%s)', rgx$square, rgx$curly, rgx$round)

  # Ensure you have the correct bracket name
  stopifnot(bracket %in% names(rgx))

  # Find your matches
  matches = str_extract_all(string, pattern = rgx[[bracket]])[[1]]

  # Remove brackets from results if needed
  if(!include.bracket) 
    matches = sapply(matches, function(m) substr(m, 2, nchar(m)-1))

  unname(matches)
}



j <- "What kind of cheese isn't your cheese? {wonder} Nacho cheese! [groan] (Laugh)"  
bracketXtract(j)
# [1] "{wonder}" "[groan]"  "(Laugh)" 
bracketXtract(j, bracket = "square")
# [1] "[groan]"
bracketXtract(j, include.bracket = F)
# [1] "wonder" "groan"  "Laugh" 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...