在不同的子字符串出现N次后删除所有子字符串实例

时间:2015-12-09 22:12:05

标签: regex r gsub

我一直试图替换角色' - '与' Z'但只有在字符串中以2个或更多的Z进行。

border: none; padding: 0;

我在第二次出现之前或之后取消所有内容都取得了一些成功,但在保留其他所有内容的同时,却无法取代所需的角色。没有受助者,Z或 - 将在字符串中。

2 个答案:

答案 0 :(得分:4)

这不是一个简单的正则表达式,但您仍然可以使用它来实现您的需要。

input = c("XX-XXZZXX-XZXXXXX", "XX-XXXZXXZXZXXX", "XXXXXZXXXZXXZX-X", 
"XXXZXXXZXZXZXXX", "XZXXX-XXXZXZXXX", "XX-XXX-ZZX", "XXZX-XXZXXX-XZ", 
"XZXZXX-XXZXXZXX")
gsub("(?:^([^Z]*Z){2}|(?!^)\\G)[^-]*\\K-", "Z", input, perl=T)

请参阅IDEONE demo

正则表达式只匹配以Z结尾的两个块(以确保从头开始有两个Z),然后是连字符和连字符的任何字符。只有连字符被gsub替换,因为我们省略了与\K运算符匹配的内容。我们匹配由于\G运算符导致的所有后续连字符,该运算符与上一次成功匹配后的位置匹配。

解释

  • (?:^([^Z]*Z){2}|(?!^)\\G) - 匹配2个替代方案:
    • ^([^Z]*Z){2} - 字符串开头(^)后跟2次出现({2})子字符串,其中包含除Z以外的0个或多个字符([^Z]* })后跟Z或......
    • (?!^)\\G - 上一次成功比赛结束
  • [^-]*\\K - 匹配-以外的0个或更多字符0次或更多次,并使用\K
  • 省略整个匹配的文字
  • - - 一个字面连字符,将替换为Z

此处需要perl=T

答案 1 :(得分:1)

正如@ stribizhev的答案所证明的那样,在正则表达式中脱离我的联盟,但是你可以通过简单地拆分整个字符串,计算Z的出现次数,并逐出后续{{{ 1}}:

-