R中的gsub正则表达式 - 忽略换行符号

时间:2018-04-26 18:49:33

标签: r regex newline gsub

这是一个可重复的例子

S0 <- "\n3 4 5"
S1 <- "\n3   5"

我想使用gsub和以下正则表达式模式( R外部 - 在regex101中测试)返回数字。这个正则表达式应该忽略\n它们是否一起出现。

([^\\n])(\s{1})?

我不是在寻找一种方法来匹配具有根本不同模式的数字 - 我想知道如何使上述模式在R 中起作用。以下内容对我不起作用

gsub("([^\\\n])(\\s{1})?", "\\1", S0)
gsub("([^[\\\]n])(\\s{1})?", "\\1", S1)

输出应为

#S0 - 345
#S1 - 3 5

3 个答案:

答案 0 :(得分:2)

由于您特别希望该正则表达式有效,因此您可以匹配并选择| product_ID | Image1 | Image2 | Image3 | |------------|-------------------------------|-------------------------------|-------------------------------| | 1 | http://example.com/images/abc | http://example.com/images/def | http://example.com/images/ghi | | 2 | http://example.com/images/abc | http://example.com/images/def | (null) | | 3 | http://example.com/images/rrr | http://example.com/images/qqq | http://example.com/images/zqr | (使用\n):

(\n)?

请注意,如果你使用像https://regex101.com/这样的正则表达式测试程序,那么它是正确的,它可以在没有额外gsub("(\n)?([^\\n])(\\s{1})", "\\2", S0) #[1] "345" gsub("(\n)?([^\\n])(\\s{1})", "\\2", S1) #[1] "3 5" 的情况下工作。但是,我认为在R中你必须匹配更多的捕获组才能正常工作。

答案 1 :(得分:2)

regex101(PCRE)中的([^\\n])(\s{1})?模式匹配的字符串与gsub中没有perl=TRUE时使用的相同模式匹配(即,当它由TRE正则表达式库处理时)。如果您使用perl=TRUE并使用gsub("([^\\\\n])(\\s{1})?", "\\1", S1, perl=TRUE),它们的工作方式相同。

PCRE Regex ([^\\n])(\s{1}) 的内容是什么?

具有PCRE选项的正则表达式测试器中的此模式匹配:

  • ([^\\n]) - \n以外的任何字符(放入第1组)
  • (\s{1})? - 将任何单个空白字符串匹配并捕获到第2组中,可选地,1或0次。

请注意,此模式与第一个捕获组中的任何非换行符都不匹配,如果是[^\n],它将匹配任何非换行符。

现在,与gsub相同的正则表达式将是

gsub("([^\n])(\\s{1})?", "\\1", S1)               # OR
gsub("([^\\\\n])(\\s{1})?", "\\1", S1, perl=TRUE)

为什么不同数量的反斜杠?因为第一个正则表达式是使用TRE正则表达式库处理的,并且在这些模式中,在括号表达式中,没有正则表达式转义符被解析, \n被视为2个单独的字符。在PCRE模式中,perl=TRUE[...]被称为字符类,在其中,您可以定义正则表达式转义,从而定义\正则表达式escape char应该加倍(也就是说,在R字符串文字内部,它应该是四倍,因为你需要\来转义\以使R引擎“看到”一个反斜杠。)

实际上,如果您想匹配换行符,只需在正则表达式模式中使用\n,您可以使用"\n""\\n"作为TRE和PCRE正则表达式引擎解析LF和\n正则表达式转义作为换行符匹配模式。这四个是等价的:

gsub("\n([^\n])(\\s{1})?", "\\1", S1)
gsub("\\n([^\n])(\\s{1})?", "\\1", S1)
gsub("\n([^\\\\n])(\\s{1})?", "\\1", S1, perl=TRUE)
gsub("\\n([^\\\\n])(\\s{1})?", "\\1", S1, perl=TRUE)

如果\n必须是可选的,只需在其后添加?量词,就不需要将其包含在一个组中:

gsub("\n?([^\n])(\\s{1})?", "\\1", S1)
        ^

进一步简化:

gsub("\n?([^\n])\\s?", "\\1", S1)

另外,如果您要[^\n]来匹配除换行符之外的所有字符,请使用.(?n)内联修饰符:

gsub("(?n)(.)(\\s{1})?", "\\1", S1)

请参阅R demo online

答案 2 :(得分:0)

有几个问题。这不是S对象中的反斜杠(它是一个转义操作符而不是一个字符),并且有一个可以否定的预定义数字字符类:

gsub("[^[:digit:]]", "", S)
[1] "345"

如果另一方面你想要排除换行符和空格,可以通过删除其中一个转义运算符来完成,因为除了字符类中存在的一小组特殊字符外,不需要它们。上下文:

gsub("[\n ]", "", S)
[1] "345"