提取正则表达式匹配

时间:2010-02-03 13:49:25

标签: regex r

我正在尝试从字符串中提取数字。

在字符串[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"

我遗漏了一个小细节。

12 个答案:

答案 0 :(得分:144)

使用新的stringr包,它包装了所有现有的正则表达式,以一致的语法运行,并添加了一些缺少的:

library(stringr)
str_locate("aaa12xxx", "[0-9]+")
#      start end
# [1,]     4   5
str_extract("aaa12xxx", "[0-9]+")
# [1] "12"

答案 1 :(得分:69)

说“忽略标准功能'可能有点仓促。 - ?gsub的帮助文件甚至特别引用了'另请参阅':

  

'regmatches'用于根据结果提取匹配的子串   'regexpr','gregexpr'和'regexec'。

所以这会起作用,而且相当简单:

txt <- "aaa12xxx"
regmatches(txt,regexpr("[0-9]+",txt))
#[1] "12"

答案 2 :(得分:22)

也许

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

答案 3 :(得分:12)

您可以使用PERL正则表达式'懒惰匹配:

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

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

答案 4 :(得分:4)

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

gsub('([[:alpha:]]+)([0-9]+)([[:alpha:]]+)', '\\2', "aaa12xxx")

答案 5 :(得分:3)

一种方式是:

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来删除你不希望留下你想要的东西。

答案 6 :(得分:2)

在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

答案 7 :(得分:1)

另一种解决方案:

temp = regexpr('\\d', "aaa12xxx");
substr("aaa12xxx", temp[1], temp[1]+attr(temp,"match.length")[1])

答案 8 :(得分:1)

此问题的解决方案

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

[[[:digit:]] :数字[0-9]

{1,} :至少匹配1次

答案 9 :(得分:0)

这些方法与任何不匹配的行为之间的一个重要区别。例如,如果所有位置都没有匹配,则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  

答案 10 :(得分:0)

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

SET @discriminator = 0;
SET @p1 = null;
SET @p2 = null;

CREATE TEMPORARY TABLE temp_rows(
    `id` INT PRIMARY KEY,
    `index` INT,
    `col1` COL1TYPE,
    `col2` COL2TYPE
);

INSERT INTO temp_rows (`index`, `col1`, `col2`, `id`)
SELECT CASE WHEN @p1 != col1 OR @p2 != col2 THEN @discriminator := 0 ELSE @discriminator := @discriminator + 1 END AS 'index', 
    @p1 := col1 AS 'col1', 
    @p2 := col2 AS 'col2',
    id
FROM `schema`.table
ORDER BY col1, col2, id desc;

DELETE FROM table WHERE EXISTS (
     SELECT 1 FROM `temp_rows`
     WHERE table.`id` = temp_rows.`id`
);

DROP TEMPORARY TABLE temp_rows;

reprex package(v0.3.0)于2019-11-06创建

使用# install.packages("unglue") library(unglue) unglue_vec(c("aaa12xxx", "aaaARGH!xxx"), "{prefix}{number=\\d+}{suffix}", var = "number") #> [1] "12" NA 参数自动转换为数字:

convert

答案 11 :(得分:-1)

您可以使用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)