R 中的 gsub 正则表达式 - 忽略换行符
gsub regex in R - ignore newline symbol
这是一个可重现的例子
S0 <- "\n3 4 5"
S1 <- "\n3 5"
我想使用 gsub
和以下正则表达式模式(在 R 之外工作 - 在 regex101 中测试)到 return 数字。此正则表达式应忽略 \
和 n
它们是否同时出现。
([^\n])(\s{1})?
我不是在寻找一种方法来匹配具有根本不同模式的数字 - 我想知道如何让上述模式在 R 中工作。以下对我不起作用
gsub("([^\\n])(\s{1})?", "\1", S0)
gsub("([^[\\]n])(\s{1})?", "\1", S1)
输出应该是
#S0 - 345
#S1 - 3 5
几个问题。在你的 S 对象中不是反斜杠(它是一个转义运算符而不是一个字符)并且有一个预定义的数字字符 class 可以取反:
gsub("[^[:digit:]]", "", S)
[1] "345"
另一方面,如果您想排除换行符和空格,可以通过删除其中一个转义运算符来完成,因为除了字符 class 上下文:
gsub("[\n ]", "", S)
[1] "345"
由于您特别希望该正则表达式起作用,您可以匹配和可选 \n
(使用 (\n)?
):
gsub("(\n)?([^\n])(\s{1})", "\2", S0)
#[1] "345"
gsub("(\n)?([^\n])(\s{1})", "\2", S1)
#[1] "3 5"
请注意,您是对的,如果您使用像这样的正则表达式测试器:https://regex101.com/ 它可以在没有额外 "(\n)?"
的情况下工作。但是,我认为在 R 中你必须匹配更多才能使捕获组正常工作。
regex101 (PCRE) 中的 ([^\n])(\s{1})?
模式与 gsub
中使用的相同模式匹配不同的字符串,而没有 perl=TRUE
(即,当它由 TRE regex 库处理时).如果您使用 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
、[...]
被称为 字符 类 并且在它们内部,您可以定义正则表达式转义,因此\
正则表达式转义字符应该加倍(也就是说,在 R 字符串文字内部,它应该是四倍,因为你需要一个 \
来将 R 引擎的 \
转义为 "see" 一个反斜杠)。
实际上,如果你想匹配一个换行符,你只需要在正则表达式模式中使用\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。
这是一个可重现的例子
S0 <- "\n3 4 5"
S1 <- "\n3 5"
我想使用 gsub
和以下正则表达式模式(在 R 之外工作 - 在 regex101 中测试)到 return 数字。此正则表达式应忽略 \
和 n
它们是否同时出现。
([^\n])(\s{1})?
我不是在寻找一种方法来匹配具有根本不同模式的数字 - 我想知道如何让上述模式在 R 中工作。以下对我不起作用
gsub("([^\\n])(\s{1})?", "\1", S0)
gsub("([^[\\]n])(\s{1})?", "\1", S1)
输出应该是
#S0 - 345
#S1 - 3 5
几个问题。在你的 S 对象中不是反斜杠(它是一个转义运算符而不是一个字符)并且有一个预定义的数字字符 class 可以取反:
gsub("[^[:digit:]]", "", S)
[1] "345"
另一方面,如果您想排除换行符和空格,可以通过删除其中一个转义运算符来完成,因为除了字符 class 上下文:
gsub("[\n ]", "", S)
[1] "345"
由于您特别希望该正则表达式起作用,您可以匹配和可选 \n
(使用 (\n)?
):
gsub("(\n)?([^\n])(\s{1})", "\2", S0)
#[1] "345"
gsub("(\n)?([^\n])(\s{1})", "\2", S1)
#[1] "3 5"
请注意,您是对的,如果您使用像这样的正则表达式测试器:https://regex101.com/ 它可以在没有额外 "(\n)?"
的情况下工作。但是,我认为在 R 中你必须匹配更多才能使捕获组正常工作。
regex101 (PCRE) 中的 ([^\n])(\s{1})?
模式与 gsub
中使用的相同模式匹配不同的字符串,而没有 perl=TRUE
(即,当它由 TRE regex 库处理时).如果您使用 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
、[...]
被称为 字符 类 并且在它们内部,您可以定义正则表达式转义,因此\
正则表达式转义字符应该加倍(也就是说,在 R 字符串文字内部,它应该是四倍,因为你需要一个 \
来将 R 引擎的 \
转义为 "see" 一个反斜杠)。
实际上,如果你想匹配一个换行符,你只需要在正则表达式模式中使用\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。