R - 使用正则表达式,设置字符串中第 n 个点之前的位置并删除后面的内容
R - using regex, set position before nth punct in string and delete what follows
我有一个大型数据框,其中有一列字符串数据,当前包含一组名称,在某些情况下还包含电子邮件地址。我想找到一个正则表达式,它允许我在那些带有电子邮件地址的情况下设置第二个逗号之前的位置,然后删除它后面的内容,这样我就剩下 "author" 列只有名字,不包括电子邮件。
> author<-c("Doe, Jane", "Smith, John", "Doe, John, johndoe@xyz.net", "Smith, Jane")
> ID<- c(1:4)
> df<-cbind(author, ID)
> df
author ID
[1,] Doe, Jane 1
[2,] Smith, John 2
[3,] Doe, John, johndoe@xyz.net 3
[4,] Smith, Jane 4
我希望输出如下所示
>df
author ID
[1,] Doe, Jane 1
[2,] Smith, John 2
[3,] Doe, John 3
[4,] Smith, Jane 4
使用sub
函数。 [^,]*
匹配任何字符但不匹配 ,
零次或多次。
> author<-c("Doe, Jane", "Smith, John", "Doe, John, johndoe@xyz.net", "Smith, Jane")
> sub("^([^,]*,[^,]*),.*", "\1", author)
[1] "Doe, Jane" "Smith, John" "Doe, John" "Smith, Jane"
> ID<- c(1:4)
> df<-cbind(author=sub("^([^,]*,[^,]*),.*", "\1", author), ID)
> df
author ID
[1,] "Doe, Jane" "1"
[2,] "Smith, John" "2"
[3,] "Doe, John" "3"
[4,] "Smith, Jane" "4"
解释:
^
断言我们在开始。
([^,]*,[^,]*)
, (...)
称为捕获组,用于捕获与该捕获组中存在的模式匹配的那些字符。在我们的例子中,捕获组中存在的模式是 [^,]*,[^,]*
。我已经提到这个 [^,]*
匹配任何字符但不匹配逗号,零次或多次。所以 [^,]*,[^,]*
匹配从开始到第二个逗号为止的所有字符。 ([^,]*,[^,]*)
捕获那些匹配的字符并将其存储到组索引 1 中。我们可以通过指定它的索引号来引用捕获组中存在的字符。这称为 反向引用 。
,.*
现在匹配第二个逗号和后面的零个或多个字符。
sub
和 gsub
函数会将所有匹配的字符替换为替换部分提到的字符串。所以在我们的例子中,所有匹配的字符都被组索引 1 中的字符替换。这就是我们在替换部分使用 \1
的原因。
这不是正则表达式,但适用于这种情况。为此,我维护的 qdap 包具有 beg2char
(字符串开头)。您可以指定字符和哪一个(这里我们想要第二个)。补函数是char2end
:
library(qdap)
df[, "ID"] <- beg2char(author, ",", 2)
## author ID
## [1,] "Doe, Jane" "Doe, Jane"
## [2,] "Smith, John" "Smith, John"
## [3,] "Doe, John, johndoe@xyz.net" "Doe, John"
## [4,] "Smith, Jane" "Smith, Jane"
我有一个大型数据框,其中有一列字符串数据,当前包含一组名称,在某些情况下还包含电子邮件地址。我想找到一个正则表达式,它允许我在那些带有电子邮件地址的情况下设置第二个逗号之前的位置,然后删除它后面的内容,这样我就剩下 "author" 列只有名字,不包括电子邮件。
> author<-c("Doe, Jane", "Smith, John", "Doe, John, johndoe@xyz.net", "Smith, Jane")
> ID<- c(1:4)
> df<-cbind(author, ID)
> df
author ID
[1,] Doe, Jane 1
[2,] Smith, John 2
[3,] Doe, John, johndoe@xyz.net 3
[4,] Smith, Jane 4
我希望输出如下所示
>df
author ID
[1,] Doe, Jane 1
[2,] Smith, John 2
[3,] Doe, John 3
[4,] Smith, Jane 4
使用sub
函数。 [^,]*
匹配任何字符但不匹配 ,
零次或多次。
> author<-c("Doe, Jane", "Smith, John", "Doe, John, johndoe@xyz.net", "Smith, Jane")
> sub("^([^,]*,[^,]*),.*", "\1", author)
[1] "Doe, Jane" "Smith, John" "Doe, John" "Smith, Jane"
> ID<- c(1:4)
> df<-cbind(author=sub("^([^,]*,[^,]*),.*", "\1", author), ID)
> df
author ID
[1,] "Doe, Jane" "1"
[2,] "Smith, John" "2"
[3,] "Doe, John" "3"
[4,] "Smith, Jane" "4"
解释:
^
断言我们在开始。([^,]*,[^,]*)
,(...)
称为捕获组,用于捕获与该捕获组中存在的模式匹配的那些字符。在我们的例子中,捕获组中存在的模式是[^,]*,[^,]*
。我已经提到这个[^,]*
匹配任何字符但不匹配逗号,零次或多次。所以[^,]*,[^,]*
匹配从开始到第二个逗号为止的所有字符。([^,]*,[^,]*)
捕获那些匹配的字符并将其存储到组索引 1 中。我们可以通过指定它的索引号来引用捕获组中存在的字符。这称为 反向引用 。,.*
现在匹配第二个逗号和后面的零个或多个字符。sub
和gsub
函数会将所有匹配的字符替换为替换部分提到的字符串。所以在我们的例子中,所有匹配的字符都被组索引 1 中的字符替换。这就是我们在替换部分使用\1
的原因。
这不是正则表达式,但适用于这种情况。为此,我维护的 qdap 包具有 beg2char
(字符串开头)。您可以指定字符和哪一个(这里我们想要第二个)。补函数是char2end
:
library(qdap)
df[, "ID"] <- beg2char(author, ",", 2)
## author ID
## [1,] "Doe, Jane" "Doe, Jane"
## [2,] "Smith, John" "Smith, John"
## [3,] "Doe, John, johndoe@xyz.net" "Doe, John"
## [4,] "Smith, Jane" "Smith, Jane"