提取正则表达式匹配

133
我想从字符串中提取一个数字。我想对字符串 "aaa12xxx" 执行类似于 [0-9]+ 的操作,以获取 "12"。我认为代码应该是这样的:
> grep("[0-9]+", "aaa12xxx", value=TRUE)
[1] "aaa12xxx"

然后我想到了...

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

但我做了一些事情,得到了某种形式的回应:

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

我忽略了一个小细节。

13个回答

1
使用包unglue,我们将执行以下操作:

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

2019年11月6日由reprex package (v0.3.0)创建

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

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

0
虽然你说你想从"aaa12xxx"中提取"12",但实际上你想要的是12。在这种情况下,预装的utils包中的strcapture函数是一个非常安全且强大的解决方案。
strcapture(pattern = "[^\\d]*(\\d+)[^\\d]*", x = "aaa12xxx", proto = list(my_val = integer()), perl = TRUE)
#>   my_val
#> 1     12

2023-07-12由reprex package (v2.0.1)创建


与基于stringi/stringr的解决方案相比,它允许您使用更强大的PCRE - jan-glx

-3
你可以使用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();
    }
}
    };

在R中调用为


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)

5
这是完全不必要的。请查看“thelatemail”或“Robert”的答案,其中包含R内的简单解决方案。 - Daniel Hoop

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接