Regex gsub R区分省略号和句点

Regex gsub R区分省略号和句点,regex,r,gsub,Regex,R,Gsub,text=“堆栈溢出…是一个流行的网站。” 我想把标点符号和单词分开。输出应为: “堆栈溢出…是一个流行的网站。” 当然,命令gsub(“\\.”,“\\.”,text,fixed=FALSE)返回: “堆栈溢出…是一个流行的网站。”,因为它不区分句点和省略号(暂停点)。简而言之,当在文本中发现三个句点时,R应该把它们看作是一个标点符号。尝试 gsub("(?<=\\.)$|(?<=\\w)(?=\\.)", " ", text, perl=TRUE) #[1] "stack ove

text=“堆栈溢出…是一个流行的网站。”

我想把标点符号和单词分开。输出应为:

“堆栈溢出…是一个流行的网站。”

当然,命令
gsub(“\\.”,“\\.”,text,fixed=FALSE)
返回:

“堆栈溢出…是一个流行的网站。”
,因为它不区分句点和省略号(暂停点)。简而言之,当在文本中发现三个句点时,R应该把它们看作是一个标点符号。

尝试

gsub("(?<=\\.)$|(?<=\\w)(?=\\.)", " ", text, perl=TRUE)
#[1] "stack overflow ... is a popular website . "

gsub("(?<=\\.)$|(?<=\\w)(?=\\.)", " ", "aaa...", perl=TRUE)
#[1] "aaa ... "

gsub("(?<=\\.)(?=$|\\w)|(?<=\\w)(?=\\.)", " ", "aaa...bbb", perl=TRUE)
#[1] "aaa ... bbb"

gsub((?我认为非环顾式方法将更加高效和可读:

text="stack overflow... is a popular website."
gsub("*[[:space:]]*(\\.+)[[:space:]]*", " \\1 ", text)
## => [1] "stack overflow ... is a popular website . "

我更新了帖子,因为标点前后都需要空格

(\\.+)
周围的
[[:space:][]*
匹配零个或多个空格,
(\\.+)
将匹配一个或多个句点。
(…)
组成一个捕获组,其值存储在一个编号的缓冲区1中,我们可以使用替换模式中的
\1
反向引用来访问该缓冲区。因此,
\1
被替换为模式捕获的句点。捕获比使用lookaround更有效,因为在t之前/之后没有检查文本的开销他现在的职位

现在,如果您需要处理所有标点符号,请使用
[[:punct:]

gsub("[[:space:]]*([[:punct:]]+)[[:space:]]*", " \\1 ", text)
见:

[:点播:

标点符号:
!“\$%&'()*+,-./:;<=>?@[\]^{124;}.

:

连字号更新 要避免匹配连字符的单词,可以匹配并跳过由单词边界包围的
-

text="Hi!stack-overflow... is a popular website, I visit it every day."
gsub("\\b-\\b(*SKIP)(*F)|\\s*(\\p{P}+)\\s*", " \\1 ", text, perl=T)
## => [1] "Hi ! stack-overflow ... is a popular website , I visit it every day . "

请参见

在大量评论之后,此正则表达式应该最适合您的需要:

(?:\b| )([.,:;!]+)(?: |\b)

要在R中使用它,反斜杠必须加倍

因此,我们最终得出以下结论:

text<-c('Hi!stack-overflow... is a popular website, I visit it every day.',
    'aaa...',
    'AAA...B"B"B',
    'AA .BBB #unlikely to happen but managed anyway')

> gsub('(?:\\b| )([.,:;!]+)(?: |\\b)',' \\1 ',text)
[1] "Hi ! stack-overflow ... is a popular website , I visit it every day . "
[2] "aaa ... "                                                              
[3] "AAA ... B\"B\"B"                                                       
[4] "AA . BBB #unlikely to happen but managed anyway"     
text gsub('(?:\\b |)([,:;!]+)(?:\\b)',\\1',text)
[1] “嗨!stack overflow…是一个很受欢迎的网站,我每天都访问它。”
[2] “aaa…”
[3] “AAA…B\'B\'B”
[4] “AA.BBB#不太可能发生,但无论如何都能控制”

gsub((\\.+),“\\1”,text,fixed=FALSE)
does…(或
gsub(([:punct:]+),“\\1”,text,fixed=FALSE)
用于任何类型的标点符号)只有句点,其他标点符号呢?@Stribizev所有标点符号都应该与单词分开,但省略号应该被视为单个实体,并且在过程中不被分开(\\b([:punct:]]+),“\\1”,text)
应该这样做,但在这个问题中,我只对从单词中分离句点和省略号感兴趣(我认为从标题中可以清楚看出)…原因是我有其他命令来处理其他标点符号,并保留单词内的破折号、撇号(我喜欢)等等。非常感谢。如果你能简单地解释一下正则表达式所说的话,那就太好了。这可能不是这个任务中最有效的正则表达式。好的,让我们开始吧,我想我的帖子会有很多编辑。@Antoine会加上一些解释。在另一个解决方案中发现错误时被带走了。@CathG:我以前也写过同样的评论或者你删除了它,但你的不正确,因为空格不是替换模式中应该出现的位置。当你对我的解决方案发表一些评论时,这不是在结尾后显示空格
(我是指查看OP的预期输出)重复我的上述内容(在Q下),我会测试单词边界的存在,以避免将现有空格加倍,并使用标点字符类,如果有,则只替换前导空格。我是在开玩笑,但我在标点符号前后都加了空格,我认为这是OP想要的。但这只是一个注释,给人一个提示…@Tensibai:No问题:)为什么要使用
(?:\b |)呢?
?您在这里的意图是什么?为了确保我们在单词边界或空格之间,例如,为了避免在笑脸中被空格标点包围,需要进行一种无关的测试。但是,这些组是可选的。如果您将它们设置为强制性的,这将起作用。
text<-c('Hi!stack-overflow... is a popular website, I visit it every day.',
    'aaa...',
    'AAA...B"B"B',
    'AA .BBB #unlikely to happen but managed anyway')

> gsub('(?:\\b| )([.,:;!]+)(?: |\\b)',' \\1 ',text)
[1] "Hi ! stack-overflow ... is a popular website , I visit it every day . "
[2] "aaa ... "                                                              
[3] "AAA ... B\"B\"B"                                                       
[4] "AA . BBB #unlikely to happen but managed anyway"