R:根据模式删除字符串的第一部分和最后部分

时间:2015-04-09 05:58:59

标签: r string gsub

此字符串是债券的代码:OAT 3 25/32 7/17/17。我想提取3 25/32的优惠券率,并将其读作3 + 25/323.78125。现在,我一直在尝试使用OAT删除日期和名称gsub,但我遇到了一些问题。

这是删除日期的代码:

tkr.bond <- 'OAT 3 25/32 7/17/17'
tkr.ptrn <- '[0-9][[:punct:]][0-9][[:punct:]][0-9]'
gsub(tkr.ptrn, "", tkr.bond)

然而它给了我相同的字符串。当我在模式中使用[0-9][[:punct:]][0-9]时,我设法删除部分日期,但它也会删除债券的优惠券利率的小数部分。

棘手的是找到一个不涉及优惠券模式的解决方案,因为代码具有以下形式:名称优惠券日期,因此,使用优惠券的特定模式可能会限制解决方案的范围。例如,如果股票代码是OAT 0 7/17/17,则优惠券为零。

4 个答案:

答案 0 :(得分:2)

只需用空字符串替换第一个和最后一个单词。

> tkr.bond <- 'OAT 3 25/32 7/17/17'
> gsub("^\\S+\\s*|\\s*\\S+$", "", tkr.bond)
[1] "3 25/32"

使用gsubfn功能按顺序使用替换部件中的功能。

> gsubfn("^\\S+\\s+(\\d+)\\s+(\\d+)/(\\d+).*", ~ as.numeric(x) + as.numeric(y)/as.numeric(z), tkr.bond)
[1] "3.78125"

<强>更新

> tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
> m <- gsub("^\\S+\\s*|\\s*\\S+$", "", tkr.bond1)
> gsubfn(".+", ~ eval(parse(text=x)), gsub("\\s+", "+", m))
[1] "3.78125" "0" 

答案 1 :(得分:1)

尝试

eval(parse(text=sub('[A-Z]+ ([0-9]+ )([0-9/]+) .*', '\\1 + \\2', tkr.bond)))
#[1] 3.78125

或者您可能需要

sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\\1', tkr.bond)
#[1] "3 25/32"

更新

tkr.bond1 <- c(tkr.bond, 'OAT 0 7/17/17')
v1 <- sub('^[A-Z]+ ([^A-Z]+) [^ ]+$', '\\1', tkr.bond1)
unname(sapply(sub(' ', '+', v1), function(x) eval(parse(text=x))))
#[1] 3.78125 0.00000

或者

vapply(strsplit(tkr.bond1, ' '), function(x)  
  eval(parse(text= paste(x[-c(1, length(x))], collapse="+"))), 0)
#[1] 3.78125 0.00000

或没有eval(parse

 vapply(strsplit(gsub('^[^ ]+ | [^ ]+$', '', tkr.bond1), '[ /]'), function(x) {
         x1 <- as.numeric(x)
         sum(x1[1], x1[2]/x1[3], na.rm=TRUE)}, 0)
#[1] 3.78125 0.00000

答案 2 :(得分:1)

与akrun的答案类似,使用sub替换。它如何运作:你把你想要的&#34;括号内的模式并将其余部分留出(同时仍然使用正则表达式字符来匹配那里的内容以及您不希望保留的内容)。然后,当你说replacement = "\\1"时,你指出整个字符串必须只用括号内的内容代替。

sub(pattern = ".*\\s(\\d\\s\\d+\\/\\d+)\\s.*", replacement = "\\1", x = tkr.bond, perl = TRUE)

# [1] "3 25/32"

然后你可以把它改成数字:

temp <- sub(pattern = ".*\\s(\\d\\s\\d+\\/\\d+)\\s.*", replacement = "\\1", x = tkr.bond, perl = TRUE)

eval(parse(text=sub(" ","+",x = temp)))

# [1] 3.78125

答案 3 :(得分:0)

你也可以在这里使用strsplit。然后评估除第一个和最后一个之外的组件。喜欢这个

> tickers <- c('OAT 3 25/32 7/17/17', 'OAT 0 7/17/17')
> 
> unlist(lapply(lapply(strsplit(tickers, " "), 
+               function(x) {x[-length(x)][-1]}),
+        function(y) {sum(
+          sapply(y, function (z) {eval(parse(text = z))}) )} ) )
[1] 3.78125 0.00000