将部分字符串转换为上部(或下部)大小写

时间:2015-10-23 07:47:08

标签: r string uppercase lowercase

我有一个带样本位置的向量,这里是一个样本:

test <- c("Aa, Heeswijk T1", "Aa, Heeswijk t1", 
          "Aa, Middelrode t2", "Aa, Middelrode p1",
          "Aa, Heeswijk t1a", "Aa, Heeswijk t3b",
          "Aa, test1 T1", "Aa, test2 t1")

这些字符串由位置名称(&#34; Aa,Heeswijk&#34;),路线代码(&#34; T1&#34;,&#34; p2&#34;,&#34)组成; t3&#34;)有时是一个子路由(&#34; a&#34;或&#34; b&#34;)。不幸的是,路线代码(t1,t2,p1,t1a)有时在上部,有时在下部。 我希望所有路线代码都是UPPER大小写,保持名称和子路由不变。我的预期结果是:

"Aa, Heeswijk T1", "Aa, Heeswijk T1", 
"Aa, Middelrode T2", "Meander Assendelft P1",
"Aa, Heeswijk T1a", "Aa, Heeswijk T3b"
"Aa, test1 T1", "Aa, test2 T1"

我查看过toupper()但是这会改变整个字符串。我也可以使用gsub:

gsub("t1","T1", test)
gsub("t2","T2", test)
#etc.

但是必须有更好的R-ish方式?!
注意:路由代码总是2个字符长,有一个字符和一个整数,前面有一个空格。因此,更改为上部的字符始终位于最后一个的第二个或第三个。

2 个答案:

答案 0 :(得分:3)

我们可以使用正则表达式的外观。我们匹配并捕获以小写字母开头的单词,后跟正则表达式预测编号((?=[0-9]))作为一个组(使用括号),在替换中我们使用\\U,然后使用捕获组将其转换为大写。

 sub('\\b([a-z])(?=[0-9])', '\\U\\1', test, perl=TRUE)
 #[1] "Aa, Heeswijk T1"       "Aa, Heeswijk T1"       "Aa, Middelrode T2"    
 #[4] "Meander Assendelft P1" "Aa, Heeswijk T1a"      "Aa, Heeswijk T3b"    

或者,如果不使用外观,我们可以使用两个捕获组来完成此操作。

 sub('\\b([a-z])([0-9])', '\\U\\1\\2', test, perl=TRUE)

更新

使用更新的测试&#39;进行测试来自OP的帖子

sub('\\b([a-z])(?=[0-9])', '\\U\\1', test, perl=TRUE)
#[1] "Aa, Heeswijk T1"   "Aa, Heeswijk T1"   "Aa, Middelrode T2"
#[4] "Aa, Middelrode P1" "Aa, Heeswijk T1a"  "Aa, Heeswijk T3b" 
#[7] "Aa, test1 T1"      "Aa, test2 T1"     

答案 1 :(得分:0)

如果您想避免正则表达式(我不建议这样做),您可以练习一些R体操:

df <- data.frame(do.call(rbind, strsplit(test, " ")), stringsAsFactors=FALSE)

现在,您已将所有内容拆分为数据框的列:

> df
   X1         X2  X3
1 Aa,   Heeswijk  T1
2 Aa,   Heeswijk  t1
3 Aa, Middelrode  t2
4 Aa, Middelrode  p1
5 Aa,   Heeswijk t1a
6 Aa,   Heeswijk t3b
7 Aa,      test1  T1
8 Aa,      test2  t1

下一步:

df[, 3]  <- paste(toupper(substr(df[, 3], 1, 2)), substr(df[, 3], 3, nchar(df[, 3])), sep="")

会做你的大写:

> df
   X1         X2  X3
1 Aa,   Heeswijk  T1
2 Aa,   Heeswijk  T1
3 Aa, Middelrode  T2
4 Aa, Middelrode  P1
5 Aa,   Heeswijk T1a
6 Aa,   Heeswijk T3b
7 Aa,      test1  T1
8 Aa,      test2  T1

最后,把它全部倒掉:

ans <- apply(df, 1, paste, collapse=" ")
ans

...给你:

> ans
[1] "Aa, Heeswijk T1"   "Aa, Heeswijk T1"   "Aa, Middelrode T2" "Aa, Middelrode P1" "Aa, Heeswijk T1a"  "Aa, Heeswijk T3b"  "Aa, test1 T1"     
[8] "Aa, test2 T1"