正则表达式R:在标点符号和单词之间添加空格,但也在标点符号之间添加空格

时间:2016-01-19 10:16:53

标签: regex r perl gsub

以下命令在标点符号和单词之间添加空格,但将相邻的标点符号保留为单个块。这对于...(它应该被视为一个单位)是正常的,但不适用于其他符号。

输入:text = "blabla!??....balabla, bla;bla:"

R命令:gsub("((?:\b| )?([.,:;!?]+)(?: |\b)?)", " \\1 ", text, perl=T)

输出:"blabla !??.... balabla , bla ; bla : "

期望的输出"blabla ! ? ? .... balabla , bla ; bla : "

2 个答案:

答案 0 :(得分:2)

测试数据: text<-'bla bla!??....bala bla, bla;bla:'

我没有找到避免两次调用gsub的方法,最保守的似乎是:

gsub('(?<=[,:;!.?])  (?=[,:;!.?])',' ',gsub("([,:;!?]|[.]+)", " \\1 ", text),perl=T)

给出:"bla bla ! ? ? .... bala bla , bla ; bla : "

我在测试数据中添加了空格,以确保它们在处理后保持清洁。

在多行上便于阅读:

gsub('(?<=[,:;!.?])  (?=[,:;!.?])', ' ', # replace 2 spaces surrounded by punctuation by only one space
     gsub(
        "([,:;!?]|[.]+)"," \\1 ", # replace punctuation by themselve surrounded by spaces
        text
     )
     ,perl=T
)

在内部部分,我们将??替换为? ?,因此我们需要在两个标点符号之间抑制此双倍空格,因为我们可能不会在文本中的任何位置执行此操作这两个空格被我们之前替换过的标点符号所包围。

由于外观不是标准R regex的一部分,我们需要在此perl=TRUE上使用gsub

答案 1 :(得分:1)

仅供参考,我不使用R,但我想我可以从问题中收集语法。我在Perl 6中玩过它并想出了这个......

my $text = "blabla!??....balabla, bla;bla:";
say $text.subst(/( '.' + | <:P> )/, {" $0 "}, :g);
# blabla !  ?  ?  .... balabla ,  bla ; bla :

所以猜测一下,我说你可以这样做吗?

gsub("(\\.+|[[:punct:]])", " \\1 ", text)

我正在做的是在一行中匹配尽可能多的.并在它们周围留出间距 - 或者 - 匹配它周围的任何标点符号和间距。 punct永远不应该与点匹配,因为正则表达式中的第一个子句应该捕获它。