合并多个空格为单个空格;删除尾部/前导空格。

91
我希望能将多个空格(制表符也可以)合并成一个,并删除前导和尾随空格。
例如...
string <- "Hi        buddy        what's up    Bro" 

为了

"Hi buddy what's up bro"

我查看了在正则表达式替换多个空格为单个空格给出的解决方案。请注意,不要将\t或\n作为toy字符串中的确切空格,并将其作为模式输入到gsub中。我想在R中实现这个。

请注意,我无法在toy字符串中输入多个空格。 谢谢。


如果你仔细阅读我的问题,你可以创建一个带有多个空格的玩具字符串,然后回答我的问题。我之前说过,我无法在玩具字符串中放置多个空格,因为StackOverflow会自动从我的查询中删除它们。 - CKM
11
gsub("^ *|(?<= ) | *$", "", x, perl = TRUE) - David Arenburg
嗨,David,那对我有用。但是你能解释一下这个模式到底是在做什么吗?即^ |(?<= ) | $它说,用空格“ ”替换所有内容,但|(?<=)|$??这正确吗?它如何解决我的问题。我想知道。 - CKM
2
请在此处查看。 - David Arenburg
1
@DavidArenburg,你给出的答案是可行的,但关闭问题的准则有所不同。我认为那个问题(虽然可能错了)与这个问题不同(我现在找不到它),因为它想要多个空格和前导空格。而这个问题则要求多个空格和前导/尾随空格。也许我在之前的帖子中错过了什么,但我不认为这两个问题是完全相同的。 - Tyler Rinker
显示剩余3条评论
9个回答

80

这似乎符合您的需求。

string <- "  Hi buddy   what's up   Bro "
library(stringr)
str_replace(gsub("\\s+", " ", str_trim(string)), "B", "b")
# [1] "Hi buddy what's up bro"

谢谢您的回复。实际上,我只想要gsub部分,因为我并不想将B替换为b。我卡住的地方是找到执行此操作的模式。您能否解释一下\s+的含义? - CKM
7
@chandresh - \\s+ 的意思是 "一个或多个空格"。 - Rich Scriven
2
值得注意的是,这是唯一一个回答涉及将 Bro 中的大写字母 b 更改为小写字母的问题,正如所示的期望结果。 - Rich Scriven
@RichScriven 我不需要转换为小写,我该如何保留大小写? - Herman Toothrot

72

或者只需尝试来自stringrsquish函数。

library(stringr)
string <- "  Hi buddy   what's up   Bro "
str_squish(string)
# [1] "Hi buddy what's up Bro"

一种现代的方法,因为 str_squish 是在 2018 年推出的,并隐藏在 str_trim 下。 - Ben Allen

43

使用单个正则表达式的另一种方法:

gsub("(?<=[\\s])\\s*|^\\s+|\\s+$", "", string, perl=TRUE)

解释(来自

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  (?<=                     look behind to see if there is:
--------------------------------------------------------------------------------
    [\s]                     any character of: whitespace (\n, \r,
                             \t, \f, and " ")
--------------------------------------------------------------------------------
  )                        end of look-behind
--------------------------------------------------------------------------------
  \s*                      whitespace (\n, \r, \t, \f, and " ") (0 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
 |                        OR
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  \s+                      whitespace (\n, \r, \t, \f, and " ") (1 or
                           more times (matching the most amount
                           possible))
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

1
为什么不使用像Adam Erickson的更简单的正则表达式呢? - Rodrigo

34

您无需导入外部库即可执行此任务:

string <- " Hi        buddy        what's up    Bro "
string <- gsub("\\s+", " ", string)
string <- trimws(string)
string
[1] "Hi buddy what's up Bro"

或者,简单说:

string <- trimws(gsub("\\s+", " ", string))

更加干净。


4
这并不依赖于任何外部库,也不像Tyler Rinker的噩梦一样使用正则表达式。不知道为什么你没有更多的赞? - Rodrigo
1
我也不明白为什么@heisenbug47半年后完全复制了我的答案。 - Adam Erickson

6
qdapRegexrm_white函数来处理这个问题:
library(qdapRegex)
rm_white(string)

## [1] "Hi buddy what's up Bro"

4
你可以尝试使用来自 qdap 的 clean 命令。
library(qdap)
library(stringr)
str_trim(clean(string))
#[1] "Hi buddy what's up Bro"

或者像@Tyler Rinker建议的那样(仅使用qdap)。
Trim(clean(string))
#[1] "Hi buddy what's up Bro"

2
你可以通过 qdap 中的 Trim(clean(string)) 来完成所有操作。 - Tyler Rinker

1
为此,无需加载任何额外的库,因为Base r包的gsub()可以完成这项工作。
不需要记住那些额外的库。 使用trimws()删除前导和尾随空格,并使用gsub()替换额外的空格,如@Adam Erickson所述。
    `string = " Hi        buddy        what's up    Bro "
     trimws(gsub("\\s+", " ", string))`

这里的\\s+匹配一个或多个空格,gsub将其替换为单个空格。

要了解任何正则表达式正在做什么,请访问@Tyler Rinker提到的链接。只需复制并粘贴您想要了解其操作的正则表达式,this会完成其余工作。


0

这似乎有效。
它不像Rich Scriven的答案那样消除句子开头或结尾的空格,但它会合并多个空格。

library("stringr")
string <- "Hi     buddy     what's      up       Bro"
str_replace_all(string, "\\s+", " ")
#> str_replace_all(string, "\\s+", " ")
#  "Hi buddy what's up Bro"

0

使用strsplit的另一种解决方案:

将文本拆分为单词,然后使用paste函数将单个单词连接起来。

string <- "Hi        buddy        what's up    Bro" 
stringsplit <- sapply(strsplit(string, " "), function(x){x[!x ==""]})
paste(stringsplit ,collapse = " ")

如果有多个文档:

string <- c("Hi        buddy        what's up    Bro"," an  example using       strsplit ") 
stringsplit <- lapply(strsplit(string, " "), function(x){x[!x ==""]})
sapply(stringsplit ,function(d) paste(d,collapse = " "))

enter image description here


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