Answers:
您可以使用PERL正则表达式的惰性匹配:
> sub(".*?([0-9]+).*", "\\1", "aaa12xx99",perl=TRUE)
[1] "12"
在这种情况下,尝试替换非数字将导致错误。
在gsubfn软件包中使用捆扎。就像应用一样,args是对象,修饰符和函数,除了对象是字符串的向量(而不是数组)并且修饰符是正则表达式(而不是空白):
library(gsubfn)
x <- c("xy13", "ab 12 cd 34 xy")
strapply(x, "\\d+", as.numeric)
# list(13, c(12, 34))
这表示要匹配x的每个分量中的一个或多个数字(\ d +),并将每个匹配项传递给as.numeric。它返回一个列表,其成分是x的各个成分的匹配向量。查看输出,我们看到x的第一部分具有一个匹配项13,而x的第二部分具有两个匹配项12和34。有关更多信息,请参见http://gsubfn.googlecode.com。
使用unglue软件包,我们将执行以下操作:
# install.packages("unglue")
library(unglue)
unglue_vec(c("aaa12xxx", "aaaARGH!xxx"), "{prefix}{number=\\d+}{suffix}", var = "number")
#> [1] "12" NA
由reprex软件包(v0.3.0)创建于2019-11-06
使用convert
参数自动转换为数字:
unglue_vec(
c("aaa12xxx", "aaaARGH!xxx"),
"{prefix}{number=\\d+}{suffix}",
var = "number",
convert = TRUE)
#> [1] 12 NA
您可以使用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)
?str_extract
我发现str_extract_all
生活又恢复了。