r - 在标点符号之间提取字符串(如果存在)
问题描述
如果存在第二个标点符号,我试图在 a 之后:
或a;
之前提取一个字符串;
,然后在 a 之后删除所有内容;
。目标结果是一个数字。
当前代码能够在:
和;
之后进行 OR操作,:
但不能;
单独或:
单独处理。
此外,gsub(|(OF 100); SEE NOTE)
它不起作用,我不确定为什么:
不排除初始值并且根本需要 gsub。
test<-c("Score (ABC): 2 (of 100); see note","Amount of ABC; 30%","Presence of ABC: negative","ABC not tested")
#works for :/;
toupper((regmatches(toupper(test), gregexpr(":\\s* \\K.*?(?=;)", toupper(test), perl=TRUE))))
#works for :
test<-toupper((regmatches(toupper(test), gregexpr(":\\s* (.*)", toupper(test), perl=TRUE))))
#removes extra characters:
test<-gsub(": |(OF 100); SEE NOTE|%|; ","",test)
#Negative to numeric:
test[grepl("NEGATIVE|<1",test)]<-0
test
预期结果:2 30 0
解决方案
这里有一些解决方案。
前两个是基础。第一个只使用非常简单的正则表达式。第二个更短,正则表达式只是稍微复杂一点。在这两种情况下,如果没有匹配项,我们将返回 NA,但如果这对您很重要,您可以在之后将 NA 替换为 0(使用NAifelse(is.na(x), 0, x)
的x
答案)。
第三个与第二个几乎相同,但在 gsubfn 中使用了 strapply。它返回 0 而不是 NA。
1) read.table用分号替换所有冒号,并将其作为分号分隔的字段读入。选择第二个这样的字段并删除第一个非数字及其之后的所有内容。然后将剩下的转换为数字。
DF <- read.table(text = gsub(":", ";", test),
as.is = TRUE, fill = TRUE, sep = ";", strip.white = TRUE)
as.numeric(sub("\\D.*", "", DF$V2))
##[1] 2 30 NA
2) strcapture 从不是冒号或分号的起始字符开始匹配,然后匹配冒号或分号,然后匹配空格,最后捕获数字。返回转换为数字的捕获数字。
strcapture("^[^:;]+[;:] (\\d+)", test, list(num = numeric(0)))$num
##[1] 2 30 NA
3) strapply 使用与 (2) 中相同的模式将匹配转换为数字,如果匹配为空则返回 0。
library(gsubfn)
strapply(test, "^[^:;]+[;:] (\\d+)", as.numeric, simplify = TRUE, empty = 0)
## [1] 2 30 0
推荐阅读
- jquery - 无法将数组作为表单参数发送
- python - 如何在python中的大集合中找到最接近的字符串匹配?
- python - RASA 与 Twilio 的集成
- javascript - 尽管属性已更改,但组件不会再次呈现
- css - 如何使用 css 选择器选择标签 html 的内容?
- java - Android:Firebase 实时数据库聊天中已签名 apk 的消息密钥已更改
- powerbi - Power BI 条形图
- doxygen - 如何在 Doxygen 配置中使用 INPUT 作为 INCLUDE_PATH?
- c++ - __cdecl 和 (void) 是什么意思?
- android - 有没有一种方法可以让我们使用 jsoup 从网页获取数据并将其显示为 android 中的列表视图?