R正则表达式删除除字母,撇号和指定的多字符字符串之外的所有字符串

时间:2015-02-27 06:48:09

标签: regex r string

是否有一个R正则表达式删除除字母,撇号和指定的多字符串之外的所有字符串? “指定的多字符串”是任意的并且具有任意长度。我们来说"~~"&在这种情况下&&(因此应删除~& &,但不应删除~~& &&

我在这里:

gsub("[^ a-zA-Z']", "", "I like~~cake~too&&much&now.")

给出了:

## [1] "I like~~cake~toomuchnow"

和...

gsub("[^ a-zA-Z'~&]", "", "I like~~cake~too&&much&now.")

...给出

## "I like~~cake~too&&much&now"

如何编写R正则表达式:

"I like~~caketoo&&muchnow"

编辑 Casimir和BrodieG的角落案件......

我期待这种行为:

x <- c("I like~~cake~too&&much&now.", "a~~~b", "a~~~~b", "a~~~~~b", "a~&a")

## [1] "I like~~caketoo&&muchnow." "a~~b"                     
## [3] "a~~~~b"                    "a~~~~b"                   
## [5] "aa" 

目前的方法都没有给出这一点。

3 个答案:

答案 0 :(得分:3)

单向,匹配/捕获“指定的多字符串”,同时替换其他字符串。

gsub("(~~|&&)|[^a-zA-Z' ]", "\\1", x)

# [1] "I like~~caketoo&&muchnow" "a~~b"                    
# [3] "a~~~~b"                   "a~~~~b"                  
# [5] "aa"  

答案 1 :(得分:2)

(?<![&~])[^ a-zA-Z'](?![&~])

试试这个。参见演示。使用perl=True选项。

https://regex101.com/r/wU7sQ0/25

答案 2 :(得分:1)

您可以使用此模式:

gsub("[A-Za-z ']*(?:(?:~~|&&)[A-Za-z ']*)*\\K(?:[^A-Za-z ']|\\z)", "", x, perl=TRUE)

online demo

我们的想法是建立一个永远真实的模式,即这句话的翻译:

我要保留的子字符串后面跟着一个我要删除的字符或字符串的结尾

因此,您需要做的就是描述您想要保留的子字符串:

[A-Za-z ']*(?:(?:~~|&&)[A-Za-z ']*)*

请注意,由于此子模式是可选的(它匹配空字符串)和贪婪,整个模式永远不会失败,无论字符串上的位置如何,所以所有匹配都是连续的(不需要从开始到结尾添加\G锚点。

出于同样的原因,没有必要添加占有量词或使用原子组来防止灾难性的回溯,因为(?:[^A-Za-z ']|\\z)不能失败。

此模式允许在几个步骤中替换字符串,但您可以更多地改进它:

  • 如果您通过回溯控制动词(*COMMIT)避开最后一场比赛(因为它只匹配您要保留的字符或结束前的空字符串)

一旦到达字符串末尾,它就强制正则表达式引擎停止搜索:

[A-Za-z ']*(?:(?:~~|&&)[A-Za-z ']*)*\\K(?:[^A-Za-z ']|\\z(*COMMIT).)
  • 如果您使模式能够匹配一个匹配中的多个特殊字符:

(除非他们是~&

[A-Za-z ']*(?:(?:~~|&&)[A-Za-z ']*)*\\K(?:[^A-Za-z '][^A-Za-z '~&]*|\\z(*COMMIT).)

demo