在R中除了撇号外,删除所有标点符号

32

我希望使用R的gsub函数从文本中移除所有标点符号,但保留撇号。我对正则表达式还比较陌生,正在学习。

例子:

x <- "I like %$@to*&, chew;: gum, but don't like|}{[] bubble@#^)( gum!?"
gsub("[[:punct:]]", "", as.character(x))

当前输出(“don't”中不带撇号)

[1] "I like to chew gum but dont like bubble gum"

期望的输出(我希望don't中的撇号保留)

[1] "I like to chew gum but don't like bubble gum"
4个回答

46
x <- "I like %$@to*&, chew;: gum, but don't like|}{[] bubble@#^)( gum!?"
gsub("[^[:alnum:][:space:]']", "", x)

[1] "I like to chew gum but don't like bubble gum"

上面的正则表达式更加简单明了。它将除了字母数字、空格或者撇号(插入符号!)之外的所有内容都替换为空字符串。

Kay,你的代码确实去掉了撇号。我认为你的意思是 gsub("[^[:alnum:][:space:]'\"]", "", x) - Tyler Rinker
我喜欢这种编码方式的直接简单。 - Tyler Rinker
5
+1 -- 在我看来,这里的想法是要提出尽可能清晰的解决方案。只需编辑第二行,将其更改为 gsub("[^[:alnum:][:space:]']", "", x),就可以了。(顺便说一句,正则表达式内部不需要反斜杠)。 - Josh O'Brien
当然,如果您的文本包含非ASCII字符(例如,多个脚本中的文本),则此答案将失去平衡。 - MichaelChirico

11
您可以使用双重否定从POSIX类“punct”中排除撇号:
[^'[:^punct:]]

代码:

x <- "I like %$@to*&, chew;: gum, but don't like|}{[] bubble@#^)( gum!?"
gsub("[^'[:^punct:]]", "", x, perl=T)

#[1] "I like to chew gum but don't like bubble gum"

ideone demo


7
这是一个例子:
>  gsub("(.*?)($|'|[^[:punct:]]+?)(.*?)", "\\2", x)
[1] "I like to chew gum but don't like bubble gum"

正是我所期望的。比我想象中要复杂得多。难怪我一直有困难。我会仔细研究你的代码。谢谢。 - Tyler Rinker
2
最后,这将是最简单的方法 gsub(".*?($|'|[^[:punct:]]).*?", "\\1", x) - kohske
感谢您的跟进。它与第一个一样有效,但更简单易懂。+1 - Tyler Rinker

5

主要是为了丰富内容,这里提供了一个使用相应名称的优秀包gsubfn()的解决方案。在这个应用中,我喜欢它允许的解决方案的表达能力:

library(gsubfn)
gsubfn(pattern = "[[:punct:]]", engine = "R",
       replacement = function(x) ifelse(x == "'", "'", ""), 
       x)
[1] "I like to chew gum but don't like bubble gum"

这里需要使用参数engine = "R",否则会使用默认的tcl引擎。它用于匹配正则表达式的规则略有不同:例如,如果用它来处理上面的字符串,则需要将pattern = "[[:punct:]$|^]"进行设置。感谢G. Grothendieck指出了这个细节。


2
一个注意点——由于某种原因,在gsubfn()调用的pattern参数中使用字符类[:punct:]时,不会像在gsub()调用中一样匹配字符$|^。因此,我必须手动添加它们。 - Josh O'Brien
2
gsubfn 默认使用 tcl 正则表达式。如果您希望使用 R 正则表达式,请使用参数 engine = "R" - G. Grothendieck
@G.Grothendieck -- 感谢您指出这一点。我已经在我的答案中加入了它。我之前是参考?gsubfn文档,其中提到pattern: Same as 'pattern' in 'gsub',我理解为应该以相同的方式指定模式。现在我明白了那句话的意思,但不知道是否需要添加额外的说明。例如:如果engine="R",则字符字符串将按照'help(regex)'文档所述进行匹配。如果使用默认的tcl引擎,则模式将按照...文档所述进行匹配。无论如何,感谢您对该软件包的工作! - Josh O'Brien

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