替换字符串中前N个句点

6

region = 2 时,我希望将 my.string 的前14个点替换为14个零。其他的点应该保持原样。

df.1 = read.table(text = "
  city  county  state region                        my.string reg1 reg2
   1      1        1      1    123456789012345678901234567890   1    0
   1      2        1      1    ...................34567890098   1    0
   1      1        2      1    112233..............0099887766   1    0
   1      2        2      1    ..............2020202020202020   1    0
   1      1        1      2    ..............00..............   0    1
   1      2        1      2    ..............0987654321123456   0    1
   1      1        2      2    ..............9999988888777776   0    1
   1      2        2      2    ..................555555555555   0    1
", sep = "", header = TRUE, stringsAsFactors = FALSE)

df.1

我不认为这个问题在这里被问过。如果是的话,很抱歉。也很抱歉没有花更多的时间寻找解决方案。快速的谷歌搜索没有找到答案。我之前在这里问了一个类似的问题:R: removing the last three dots from a string 谢谢任何帮助。
我应该澄清一下,我只想删除字符串最左边的14个连续点。如果一个字符串以一个数字开头,后面跟着14个点,那么这些14个点应该保持原样。
这是my.string的样子:
123456789012345678901234567890
...................34567890098
112233..............0099887766
..............2020202020202020
0000000000000000..............
000000000000000987654321123456
000000000000009999988888777776
00000000000000....555555555555
4个回答

8

你尝试过以下方法吗:

sub("^\\.{14}", "00000000000000", df.1$my.string )

对于条件替换,请尝试使用:

> df.1[ df.1$region ==2, "mystring"] <- 
               sub("^\\.{14}", "00000000000000", df.1$my.string[ df.1$region==2] )
> df.1
  city county state region                      my.string reg1 reg2
1    1      1     1      1 123456789012345678901234567890    1    0
2    1      2     1      1 ...................34567890098    1    0
3    1      1     2      1 112233..............0099887766    1    0
4    1      2     2      1 ..............2020202020202020    1    0
5    1      1     1      2 ..............00..............    0    1
6    1      2     1      2 ..............0987654321123456    0    1
7    1      1     2      2 ..............9999988888777776    0    1
8    1      2     2      2 ..................555555555555    0    1
                        mystring
1                           <NA>
2                           <NA>
3                           <NA>
4                           <NA>
5 0000000000000000..............
6 000000000000000987654321123456
7 000000000000009999988888777776
8 00000000000000....555555555555

2
这个能“动态”完成吗?例如:根据匹配到的.数量填充14个或更少的零?也许可以使用gsubfun实现? - Justin
当然,gsubfn 是一项非凡的发明,但我认为它不需要那种火力。 - IRTFM
谢谢。如果我对该行左侧进行微小修改,我将得到我想要的结果:df.1$my.string[df.1$region==2] <- sub("^\.{14}", "00000000000000", df.1$my.string[df.1$region==2])。 - Mark Miller

3

dwin的回答很棒。这里有一个容易理解但不太华丽的回答。

# restrict the substitution to only region == 2..
# then replace the 'my.string' column with..
df.1[ df.1$region == 2 , 'my.string' ] <- 

    # substitute.. (only the first instance!)
    # (use gsub for multiple instances)
    sub( 
        # fourteen dots
        '..............' , 
        # with fourteen zeroes
        '00000000000000' , 
        # in the same object (also restricted to region == 2
        df.1[ df.1$region == 2 , 'my.string' ] , 
        # and don't use regex or anything special.
        # just exactly 14 dots.
        fixed = TRUE 
    )

你需要转义每个点,因为在正则表达式中“.”表示任何字符。 - Justin
我喜欢所有的答案,并且都点了赞,但是现在你的答案是我最喜欢的,因为它完全按照我希望的方式返回了完整的数据集。我会等到明天或以后再打勾。 - Mark Miller
@MarkMiller 的回答更好。你应该接受他的,而不是我的。 - Anthony Damico
这不符合“字符串最左边”的要求——它只会替换它找到的第一个包含14个连续点的实例。在这里,正则表达式中的“^”锚点至关重要... - Charles
@Charles,我建议MarkMiller接受dwin的答案而不是我的原因之一是因为我的版本虽然易于理解,但有些笨拙。 :) - Anthony Damico

3
一个 data.table 解决方案:
require(data.table)
dt <- data.table(df.1)

# solution:
dt[, mystring := ifelse(region == 2, sub("^[.]{14}", 
                   paste(rep(0,14), collapse=""), my.string), 
                   my.string), by=1:nrow(dt)]

#    city county state region                      my.string reg1 reg2                       mystring
# 1:    1      1     1      1 123456789012345678901234567890    1    0 123456789012345678901234567890
# 2:    1      2     1      1 ...................34567890098    1    0 ...................34567890098
# 3:    1      1     2      1 112233..............0099887766    1    0 112233..............0099887766
# 4:    1      2     2      1 ..............2020202020202020    1    0 ..............2020202020202020
# 5:    1      1     1      2 ..............00..............    0    1 0000000000000000..............
# 6:    1      2     1      2 ..............0987654321123456    0    1 000000000000000987654321123456
# 7:    1      1     2      2 ..............9999988888777776    0    1 000000000000009999988888777776
# 8:    1      2     2      2 ..................555555555555    0    1 00000000000000....555555555555

3
    gsub('^[.]{14,14}',paste(rep(0,14),collapse=''),df.1$my.string)
"123456789012345678901234567890" "00000000000000.....34567890098" "112233..............0099887766"
[4] "000000000000002020202020202020" "0000000000000000.............." "000000000000000987654321123456"
[7] "000000000000009999988888777776" "00000000000000....555555555555"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接