我正在尝试从字符串中提取数字。
并在字符串[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"
我缺少一个小细节。
使用新的stringr包,它包装所有现有的正则表达式,以一致的语法运行,并添加一些缺少的:
library(stringr)
str_locate("aaa12xxx", "[0-9]+")
# start end
# [1,] 4 5
str_extract("aaa12xxx", "[0-9]+")
# [1] "12"
你可以用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)
说“忽略标准函数”可能有点仓促 - ?gsub
的帮助文件甚至在“另请参见”中特别引用:
'regmatches'用于根据'regexpr','gregexpr'和'regexec'的结果提取匹配的子串。
所以这会起作用,而且相当简单:
txt <- "aaa12xxx"
regmatches(txt,regexpr("[0-9]+",txt))
#[1] "12"
也许
gsub("[^0-9]", "", "aaa12xxxx")
# [1] "12"
你可以使用PERL正则表达式'懒惰匹配:
> sub(".*?([0-9]+).*", "\\1", "aaa12xx99",perl=TRUE)
[1] "12"
在这种情况下,尝试替换非数字会导致错误。
在替换中使用正则表达式和组引用中的捕获括号。括号中的任何内容都会被记住。然后他们被\ 2,第一个项目访问。第一个反斜杠转义R中的反斜杠解释,以便将其传递给正则表达式解析器。
gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")
一种方法是:
test <- regexpr("[0-9]+","aaa12456xxx")
现在,请注意regexpr为您提供字符串的起始和结束索引:
> test
[1] 4
attr(,"match.length")
[1] 5
因此,您可以将该信息与substr函数一起使用
substr("aaa12456xxx",test,test+attr(test,"match.length")-1)
我确信有更优雅的方式来做到这一点,但这是我能找到的最快的方式。或者,你可以使用sub / gsub来删除你不希望留下你想要的东西。
在gsubfn包中使用strapply。 strapply就像应用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。
另一种方案:
temp = regexpr('\\d', "aaa12xxx");
substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])
这些方法之间的一个重要区别是任何不匹配的行为。例如,如果所有位置都没有匹配,则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