R 只交换单词中间字母的顺序,如果有标点符号,则保持标点符号的顺序

R 只交换单词中间字母的顺序,如果有标点符号,则保持标点符号的顺序,r,string,list,R,String,List,我需要一个只交换单词中间的字符(在第一个字符和最后一个字符之间)的函数。如果单词由少于4个字符组成,则函数不应更改任何内容。该函数有一个名为exclude的参数,它是单词末尾潜在标点符号的向量 您可以假设只有一个可能的标点符号。如果有这样一个标记,则不应更改该标记,也不应计入实际单词的组成字符数 我的想法是 排除任何标点符号 去掉单词的第一个字母 去掉单词的最后一个字母 交换剩下的信件 加回第一个和最后一个字母以及标点符号 string假设您要颠倒中间字符的顺序: revmiddle &l

我需要一个只交换单词中间的字符(在第一个字符和最后一个字符之间)的函数。如果单词由少于4个字符组成,则函数不应更改任何内容。该函数有一个名为
exclude
的参数,它是单词末尾潜在标点符号的向量

您可以假设只有一个可能的标点符号。如果有这样一个标记,则不应更改该标记,也不应计入实际单词的组成字符数

我的想法是

  • 排除任何标点符号
  • 去掉单词的第一个字母
  • 去掉单词的最后一个字母
  • 交换剩下的信件
  • 加回第一个和最后一个字母以及标点符号

string假设您要颠倒中间字符的顺序:

revmiddle <- function(s,exclude=c(',','.','!','?')) {
    if (nchar(s)<4L) return(s);
    x <- strsplit(s,'')[[1L]];
    if (x[length(x)]%in%exclude) {
        punc <- x[length(x)];
        x <- x[-length(x)];
    } else {
        punc <- NULL;
    }; ## end if
    paste(collapse='',c(x[1L],x[seq(length(x)-1L,2L)],x[length(x)],punc));
}; ## end revmiddle()
randmiddle <- function(s,exclude=c(',','.','!','?')) {
    if (nchar(s)<4L) return(s);
    x <- strsplit(s,'')[[1L]];
    if (x[length(x)]%in%exclude) {
        punc <- x[length(x)];
        x <- x[-length(x)];
    } else {
        punc <- NULL;
    }; ## end if
    paste(collapse='',c(x[1L],sample(x[-c(1L,length(x))]),x[length(x)],punc));
}; ## end randmiddle()

要随机化中间字符的顺序,请执行以下操作:

revmiddle <- function(s,exclude=c(',','.','!','?')) {
    if (nchar(s)<4L) return(s);
    x <- strsplit(s,'')[[1L]];
    if (x[length(x)]%in%exclude) {
        punc <- x[length(x)];
        x <- x[-length(x)];
    } else {
        punc <- NULL;
    }; ## end if
    paste(collapse='',c(x[1L],x[seq(length(x)-1L,2L)],x[length(x)],punc));
}; ## end revmiddle()
randmiddle <- function(s,exclude=c(',','.','!','?')) {
    if (nchar(s)<4L) return(s);
    x <- strsplit(s,'')[[1L]];
    if (x[length(x)]%in%exclude) {
        punc <- x[length(x)];
        x <- x[-length(x)];
    } else {
        punc <- NULL;
    }; ## end if
    paste(collapse='',c(x[1L],sample(x[-c(1L,length(x))]),x[length(x)],punc));
}; ## end randmiddle()

您使用了“交换”一词来描述需求,但在代码中调用的是
sample()
,它将中间字符的顺序随机化。我对“交换”一词的本能解释是,你的意思是颠倒中间字符的顺序。你能澄清一下你是想反转还是随机化中间的字符吗?谢谢你的评论。要求是随机改变中间字母的顺序。例如,“well!”的结果应该是两个:“well!”和“wlel!”,非常感谢您的帮助!你的代码比我的更精确、更高效。一件很小的事情是,要求随机交换订单,而不是反向…但仍然非常有用@不客气!请参见随机化实现的编辑。您使用的
sample()
是正确的。
sort(unique(replicate(1e3L,randmiddle('well!'))));
## [1] "well!" "wlel!"
sort(unique(replicate(1e3L,randmiddle('hello?'))));
## [1] "hello?" "hlelo?" "hlleo?"
sort(unique(replicate(1e3L,randmiddle('Tes'))));
## [1] "Tes"