gsub() 函数中的简单正则表达式不起作用
Easy regex in gsub() function is not working
我刚开始使用 R 编程。目前,我正在著名的泰坦尼克号数据集上练习特征工程。
除其他外,我想提取数据集中人员的头衔。
我有这些:
Montvila, Rev. Juozas
Johnston, Miss. Catherine Helen
想要得到这些:
Rev.
Miss.
我自己的方法行不通。我无法弄清楚问题到底是什么:
gsub("([A-Za-z:space:]+, )|(\.[A-Za-z:space:]+)", "", data_raw$Name)
希望有人能帮助我!太棒了。
亲切的问候,
马库斯
我们可以从字符串的开头 (^
) 匹配一个或多个非白色 space 字符 (\S+
),后跟一个或多个白色 space (\s+
) 或 (|
) 使用环视匹配 .
后跟字符直到字符串末尾并将其替换为空白 (""
)
gsub("^\S+\s+|(?<=\.).*$", "", str1, perl = TRUE)
#[1] "Rev." "Miss."
或者另一种选择是将字符捕获为一个组 (([^.]+\.)
),并在替换中使用该捕获组的反向引用 (\1
)。
sub("^[^,]+,\s+([^.]+\.).*", "\1", str1)
#[1] "Rev." "Miss."
数据
str1 <- c("Montvila, Rev. Juozas", "Johnston, Miss. Catherine Helen")
我建议使用一个正则表达式来替换所有文本,但最后一个字母块后跟一个点。
> x <- c("Montvila, Rev. Juozas", "Johnston, Miss. Catherine Helen")
> sub("^.*\b([[:alpha:]]+\.).*", "\1", x)
[1] "Rev." "Miss."
或更简单的regmatches
解决方案:
> unlist(regmatches(x, regexpr("[[:alpha:]]+\.", x)))
[1] "Rev." "Miss."
或者,如果您需要检查一个点,但 "exclude" 它来自匹配项,请使用带有 regmatches
(perl=TRUE
) 的 PCRE 正则表达式,允许在模式:
> unlist(regmatches(x, regexpr("[[:alpha:]]+(?=\.)", x, perl=TRUE)))
[1] "Rev" "Miss"
这里,(?=\.)
是一个积极的前瞻,需要在 1+ 个字母后有一个 .
,但将其排除在匹配之外。
详情:
^
- 字符串的开头
.*
- 任何 0+ 个字符,直到最后一个字符为止...
\b
- 单词边界
([[:alpha:]]+\.)
- 第 1 组:一个或多个字母后跟文字 .
.*
- 到字符串末尾的任何 0+ 个字符。
使用 TRE 正则表达式,因此 .
匹配任何字符,包括换行符。
此外,在您的代码中,.
使用单个 \
转义,这会导致错误,因为 \.
是一个错误的转义序列。正则表达式转义必须用双反斜杠定义。
我刚开始使用 R 编程。目前,我正在著名的泰坦尼克号数据集上练习特征工程。
除其他外,我想提取数据集中人员的头衔。
我有这些:
Montvila, Rev. Juozas
Johnston, Miss. Catherine Helen
想要得到这些:
Rev.
Miss.
我自己的方法行不通。我无法弄清楚问题到底是什么:
gsub("([A-Za-z:space:]+, )|(\.[A-Za-z:space:]+)", "", data_raw$Name)
希望有人能帮助我!太棒了。
亲切的问候, 马库斯
我们可以从字符串的开头 (^
) 匹配一个或多个非白色 space 字符 (\S+
),后跟一个或多个白色 space (\s+
) 或 (|
) 使用环视匹配 .
后跟字符直到字符串末尾并将其替换为空白 (""
)
gsub("^\S+\s+|(?<=\.).*$", "", str1, perl = TRUE)
#[1] "Rev." "Miss."
或者另一种选择是将字符捕获为一个组 (([^.]+\.)
),并在替换中使用该捕获组的反向引用 (\1
)。
sub("^[^,]+,\s+([^.]+\.).*", "\1", str1)
#[1] "Rev." "Miss."
数据
str1 <- c("Montvila, Rev. Juozas", "Johnston, Miss. Catherine Helen")
我建议使用一个正则表达式来替换所有文本,但最后一个字母块后跟一个点。
> x <- c("Montvila, Rev. Juozas", "Johnston, Miss. Catherine Helen")
> sub("^.*\b([[:alpha:]]+\.).*", "\1", x)
[1] "Rev." "Miss."
或更简单的regmatches
解决方案:
> unlist(regmatches(x, regexpr("[[:alpha:]]+\.", x)))
[1] "Rev." "Miss."
或者,如果您需要检查一个点,但 "exclude" 它来自匹配项,请使用带有 regmatches
(perl=TRUE
) 的 PCRE 正则表达式,允许在模式:
> unlist(regmatches(x, regexpr("[[:alpha:]]+(?=\.)", x, perl=TRUE)))
[1] "Rev" "Miss"
这里,(?=\.)
是一个积极的前瞻,需要在 1+ 个字母后有一个 .
,但将其排除在匹配之外。
详情:
^
- 字符串的开头.*
- 任何 0+ 个字符,直到最后一个字符为止...\b
- 单词边界([[:alpha:]]+\.)
- 第 1 组:一个或多个字母后跟文字.
.*
- 到字符串末尾的任何 0+ 个字符。
使用 TRE 正则表达式,因此 .
匹配任何字符,包括换行符。
此外,在您的代码中,.
使用单个 \
转义,这会导致错误,因为 \.
是一个错误的转义序列。正则表达式转义必须用双反斜杠定义。