代码之家  ›  专栏  ›  技术社区  ›  tovare

提取正则表达式匹配项

  •  87
  • tovare  · 技术社区  · 15 年前

    [0-9]+ 悬而未决 "aaa12xxx" 得到 "12"

    > grep("[0-9]+", "aaa12xxx", value=TRUE)
    [1] "aaa12xxx"
    

    然后我想。。。

    > sub("[0-9]+", "\\1", "aaa12xxx")
    [1] "aaaxxx"
    

    但我得到了某种形式的回应:

    > sub("[0-9]+", "ARGH!", "aaa12xxx")
    [1] "aaaARGH!xxx"
    

    我遗漏了一个小细节。

    10 回复  |  直到 7 年前
        1
  •  180
  •   Collin    15 年前

    使用新的stringr软件包,该软件包以一致的语法包装所有现有正则表达式,并添加一些缺少的内容:

    library(stringr)
    str_locate("aaa12xxx", "[0-9]+")
    #      start end
    # [1,]     4   5
    str_extract("aaa12xxx", "[0-9]+")
    # [1] "12"
    
        2
  •  114
  •   thelatemail    11 年前

    说“我的朋友”可能有点草率 忽略标准函数 “-的帮助文件 ?gsub 即使是“另请参见”中的具体引用:

    regmatches,用于根据

    因此,这将起作用,而且相当简单:

    txt <- "aaa12xxx"
    regmatches(txt,regexpr("[0-9]+",txt))
    #[1] "12"
    
        3
  •  27
  •   Marek    3 年前

    gsub("[^0-9]", "", "aaa12xxxx")
    # [1] "12"
    

    它在更复杂的情况下不起作用

    gsub("[^0-9]", "", "aaa12xxxx34")
    # [1] "1234"
    
        4
  •  16
  •   Jyotirmoy Bhattacharya    15 年前

    您可以使用PERL正则表达式的惰性匹配:

    > sub(".*?([0-9]+).*", "\\1", "aaa12xx99",perl=TRUE)
    [1] "12"
    

    在这种情况下,尝试替换非数字将导致错误。

        5
  •  6
  •   Ragy Isaac    11 年前

    在正则表达式中使用捕获括号,在替换中使用组引用。括号中的任何内容都会被记住。然后,第一项\2将访问它们。第一个反斜杠在R中转义反斜杠的解释,以便将其传递给正则表达式解析器。

    gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")
    
        6
  •  5
  •   Robert    15 年前

    一种方法是:

    test <- regexpr("[0-9]+","aaa12456xxx")
    

    现在,请注意regexpr为您提供了字符串的起始索引和结束索引:

        > test
    [1] 4
    attr(,"match.length")
    [1] 5
    

    substr("aaa12456xxx",test,test+attr(test,"match.length")-1)
    

    我相信有一种更优雅的方法可以做到这一点,但这是我能找到的最快的方法。或者,您可以使用sub/gsub除去您不想要的内容,留下您想要的内容。

        7
  •  4
  •   andyyy    9 年前

    这些方法之间的一个重要区别是任何不匹配的行为。例如,如果所有位置都不匹配,则regmatches方法可能不会返回与输入长度相同的字符串

    > txt <- c("aaa12xxx","xyz")
    
    > regmatches(txt,regexpr("[0-9]+",txt)) # could cause problems
    
    [1] "12"
    
    > gsub("[^0-9]", "", txt)
    
    [1] "12" ""  
    
    > str_extract(txt, "[0-9]+")
    
    [1] "12" NA  
    
        8
  •  2
  •   G. Grothendieck    15 年前

    library(gsubfn)
    x <- c("xy13", "ab 12 cd 34 xy")
    strapply(x, "\\d+", as.numeric)
    # list(13, c(12, 34))
    

    这表示匹配x的每个分量中的一个或多个数字(\d+)并将每个匹配传递为.numeric。它返回一个列表,其组件是x的各个组件的匹配向量。查看输出,我们可以看到x的第一个分量有一个匹配项,即13,而x的第二个分量有两个匹配项,即12和34。请参阅 http://gsubfn.googlecode.com

        9
  •  2
  •   pari    9 年前

    另一个解决方案:

    temp = regexpr('\\d', "aaa12xxx");
    substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])
    
        10
  •  1
  •   Tho Vu    4 年前

    library(stringr)
    str_extract_all("aaa12xxx", regex("[[:digit:]]{1,}"))
    # [[1]]
    # [1] "12"
    

    [:数字:]

    {1,}

        11
  •  0
  •   moodymudskipper    5 年前

    使用包 脱胶 我们将做以下工作:

    # install.packages("unglue")
    library(unglue)
    unglue_vec(c("aaa12xxx", "aaaARGH!xxx"), "{prefix}{number=\\d+}{suffix}", var = "number")
    #> [1] "12" NA
    

    于2019-11-06由 reprex package

    使用 convert 要自动转换为数字的参数:

    unglue_vec(
      c("aaa12xxx", "aaaARGH!xxx"), 
      "{prefix}{number=\\d+}{suffix}", 
      var = "number", 
      convert = TRUE)
    #> [1] 12 NA
    
        12
  •  -2
  •   user2074102 user2074102    8 年前

    您可以用C++编写正则表达式函数,将它们编译成DLL,并从R调用它们。

        #include <regex>
    
        extern "C" {
        __declspec(dllexport)
        void regex_match( const char **first, char **regexStr, int *_bool)
        {
            std::cmatch _cmatch;
            const char *last = *first + strlen(*first);
            std::regex rx(*regexStr);
            bool found = false;
            found = std::regex_match(*first,last,_cmatch, rx);
            *_bool = found;
        }
    
    __declspec(dllexport)
    void regex_search_results( const char **str, const char **regexStr, int *N, char **out )
    {
        std::string s(*str);
        std::regex rgx(*regexStr);
        std::smatch m;
    
        int i=0;
        while(std::regex_search(s,m,rgx) && i < *N) {
            strcpy(out[i],m[0].str().c_str());
            i++;
            s = m.suffix().str();
        }
    }
        };
    

    打电话来

    dyn.load("C:\\YourPath\\RegTest.dll")
    regex_match <- function(str,regstr) {
    .C("regex_match",x=as.character(str),y=as.character(regstr),z=as.logical(1))$z }
    
    regex_match("abc","a(b)c")
    
    regex_search_results <- function(x,y,n) {
    .C("regex_search_results",x=as.character(x),y=as.character(y),i=as.integer(n),z=character(n))$z }
    
    regex_search_results("aaa12aa34xxx", "[0-9]+", 5)