我在R中的data.table中有一列,看起来像这样。
[1] "<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_RESULT\",\"SK190400\",
[2] "=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\",
[3] "<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\",
[4] "=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"OEE_DATA\",
[5] "<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"PING\",\"SK190400\",
但我唯一关心的是它是“UNIT_RESULT”,“UNIT_CHECKIN”,“OEE_DATA”还是“PING”,所以我想用新字符串替换每一行(“UNIT_RESULT”等)< / p>
结果应如下所示:
[1] "UNIT_RESULT"
[2] "UNIT_CHECKIN"
[3] "UNIT_CHECKIN"
[4] "OEE_DATA"
[5] "PING"
我花了很多时间试图找到如何通过自己的部分替换字符串,但没有任何显示任何有用的结果。
Replace specific characters within strings
Reference - What does this regex mean?
Test if characters in string in R
在开头函数substring(x,53,63)看起来像我的解决方案,但它只是在字符串中选择固定符号,所以除非我有所有行相同它是无用的。
任何提示?
答案 0 :(得分:1)
str_match_all
函数将正则表达式应用于字符串向量的每个元素,并仅返回匹配。因此,我们可以列出我们想要提取的所有术语,并使用paste0
将它们与|
OR运算符连接在一起,以创建一个与4个所需术语中的任何一个匹配的正则表达式。 / p>
然后我们只需将str_match_all
函数和unlist
结果列表运行到字符向量中。
strings <- c("<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_RESULT\",\"SK190400\"",
"=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\"",
"<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\"",
"=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"OEE_DATA\"",
"<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"PING\",\"SK190400\""
)
items <- c('UNIT_RESULT', 'UNIT_CHECKIN', 'OEE_DATA', 'PING')
library(stringr)
unlist(str_match_all(strings, paste0(items,collapse = '|')))
[1] "UNIT_RESULT" "UNIT_CHECKIN" "UNIT_CHECKIN" "OEE_DATA" "PING"
答案 1 :(得分:0)
另一种方法是使用str_extract
。您将字符串作为&#39;字符串&#39;论证和你给出的替代方案作为“模式”#39;参数,它会返回你的替代品,第一个出现在字符串中。
library(stringr)
DT[, newstring := str_extract(string_column, "UNIT_RESULT|UNIT_CHECKIN|OEE_DATA|PING")]
答案 2 :(得分:0)
我建议
gsub("^.*?(UNIT_RESULT|UNIT_CHECKIN|OEE_DATA|PING).*","\\1",strings,perl=TRUE)
答案 3 :(得分:0)
如果您没有搜索的有限字符串列表,我建议使用reg-ex模式。以下是根据您提供的示例工作的内容:
# Code to create example data.table
library(data.table)
dt <- data.table(f1 = c("<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_RESULT\",\"SK190400\"",
"=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\"",
"<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"UNIT_CHECKIN\",\"SK190400\"",
"=> MSG: 'MessageReq', BODY: '{\"MessageReq\":{\"Parameters\":[\"OEE_DATA\"",
"<= MSG: 'ACK', BODY: '{\"MessageRep\":{\"Parameters\":[\"PING\",\"SK190400\""
))
# Start of code to parse out values:
rex_pattern <- "(?<=(\"))[A-Z]{2,}_*[A-Z]+(?=(\"))"
dt[, .(parsed_val = regmatches(f1, regexpr(pattern = rex_pattern, f1, perl = TRUE)))]
这会给你:
parsed_val
1: UNIT_RESULT
2: UNIT_CHECKIN
3: UNIT_CHECKIN
4: OEE_DATA
5: PING
如果你真的想&#34;覆盖&#34;使用新子字符串的原始字段f1
,您可以使用以下内容:
dt[, `:=`(f1 = regmatches(f1, regexpr(pattern = rex_pattern, f1, perl = TRUE)))]