我想删除这些字符串中仅在1个字母长度的单词之间的空格 . 例如,在第一个字符串中,我想删除 AB 和 C 之间的空格,但不删除 C 和公司之间的空格 . 结果应该是:
ABC Company
XYZ Inc
S&K Co
在 gsub 中使用的正确的正则表达式是什么?
5 回答
19
这是你可以做到这一点的一种方式,看看 & 是如何混合而不是单词字符......
x <- c('A B C Company', 'XYZ Inc', 'S & K Co', 'A B C D E F G Company')
gsub('(?<!\\S\\S)\\s+(?=\\S(?!\\S))', '', x, perl=TRUE)
# [1] "ABC Company" "XYZ Inc" "S&K Co" "ABCDEFG Company"
说明:
首先,我们断言两个非空白字符不会背靠背 . 然后我们寻找和匹配空白"one or more"次 . 接下来,我们预见断言在断言下一个字符不是非空白字符时会跟随非空白字符 .
(?<! # look behind to see if there is not:
\S # non-whitespace (all but \n, \r, \t, \f, and " ")
\S # non-whitespace (all but \n, \r, \t, \f, and " ")
) # end of look-behind
\s+ # whitespace (\n, \r, \t, \f, and " ") (1 or more times)
(?= # look ahead to see if there is:
\S # non-whitespace (all but \n, \r, \t, \f, and " ")
(?! # look ahead to see if there is not:
\S # non-whitespace (all but \n, \r, \t, \f, and " ")
) # end of look-ahead
) # end of look-ahead
x <- c('A B C Company', 'XYZ Inc', 'S & K Co',
'A B C D E F G Company', 'Company A B C', 'Co A B C mpany')
foo <- function(x) {
x[nchar(x) == 1L] <- paste(x[nchar(x) == 1L], collapse = "")
paste(unique(x), collapse = " ")
}
vapply(strsplit(x, " "), foo, character(1L))
# [1] "ABC Company" "XYZ Inc" "S&K Co"
# [4] "ABCDEFG Company" "Company ABC" "Co ABC mpany"
> x <- c('A B C Company', 'XYZ Inc', 'S & K Co', 'A B C D E F G Company', ' H & K')
> gsub("\\s*\\S\\S+\\s*(*SKIP)(*F)|(?<=\\S)\\s+(?=\\S)", "", x, perl=TRUE)
[1] "ABC Company" "XYZ Inc" "S&K Co" "ABCDEFG Company"
[5] " H&K"
Explanation:
\\s*\\S\\S+\\s* 将匹配两个或多个非空格字符以及前后空格 .
(*SKIP)(*F) 导致匹配失败 .
| 现在准备从剩余的字符串中选择字符 .
(?<=\\S)\\s+(?=\\S) 匹配一个或多个以非空格开头,后跟非空格字符的空格 .
删除空格将为您提供所需的输出 .
Note: 看到最后一个元素,这个正则表达式赢得了't replace the preceding spaces at the first because the spaces at the start isn' t前面有一个非空格字符 .
5 回答
这是你可以做到这一点的一种方式,看看
&
是如何混合而不是单词字符......说明:
首先,我们断言两个非空白字符不会背靠背 . 然后我们寻找和匹配空白"one or more"次 . 接下来,我们预见断言在断言下一个字符不是非空白字符时会跟随非空白字符 .
必要的
strsplit
/paste
答案 . 这也将获得可能位于字符串中间或末尾的单个字符 .比赛迟到,但这种模式适合你
Demo
另外一个选项
你也可以通过PCRE动词
(*SKIP)(*F)
这样做Explanation:
\\s*\\S\\S+\\s*
将匹配两个或多个非空格字符以及前后空格 .(*SKIP)(*F)
导致匹配失败 .|
现在准备从剩余的字符串中选择字符 .(?<=\\S)\\s+(?=\\S)
匹配一个或多个以非空格开头,后跟非空格字符的空格 .删除空格将为您提供所需的输出 .
Note: 看到最后一个元素,这个正则表达式赢得了't replace the preceding spaces at the first because the spaces at the start isn' t前面有一个非空格字符 .