我在一些显示数字的数字中有一些错误,比如"59.34343.23";。我知道第一个点是正确的,但第二个点(或第一个点之后的任何一个)应该删除。我该如何移除这些?
我尝试在R:中使用gsub
gsub("(?<=\..*)\.", "", "59.34343.23", perl=T)
或
gsub("(?<!^[^.]*)\.", "", "59.34343.23", perl=T)
然而,它得到以下错误";无效正则表达式";。但我一直在regex测试仪中尝试相同的代码,它确实有效。我在这里犯了什么错?
您可以使用
gsub("^([^.]*\.)|\.", "\1", "59.34343.23")
gsub("^([^.]*\.)|\.", "\1", "59.34343.23", perl=TRUE)
请在线查看R演示和regex演示。
详细信息:
^([^.]*.)
-捕获组1(从替换模式中称为1
):从字符串开始的任何零个或多个字符,然后是一个.
字符(字符串中的第一个)|
-或.
-字符串中的任何其他点
由于替换1
指的是组1,并且组1只包含匹配第一个点之前和包括第一个点在内的文本之后的值,因此替换要么是这部分文本,要么是空字符串(即,第二个和所有后续出现的点都被删除)。
我们可以使用
gsub("^[^.]+\.(*SKIP)(*FAIL)|\.", "", str1, perl = TRUE)
[1] "59.3434323"
数据
str1 <- "59.34343.23"
通过指定perl = TRUE
,您可以将以下正则表达式的匹配项转换为空字符串:
^[^.]*.[^.]*K.|.
启动发动机!
如果您不熟悉K
,请将鼠标悬停在链接处的正则表达式中,以查看其效果的解释。
如果点是行中的第一个,则始终可以选择只写回点
关键功能是消耗其他点,但不将其写回
效果是删除尾随点。
下面使用分支重置来实现目标(Perl模式)。
(?m)(?|(^[^.n]*.)|().+)
更换$1
https://regex101.com/r/cHcu4j/1
(?m)
(?|
( ^ [^.n]* . ) # (1)
| ( ) # (1)
.+
)
您尝试的模式不匹配,因为在后备(?<=\..*)
中有一个不受支持的无限量词。
使用G
在第一个点之后获得连续匹配的另一种变体:
(?:^[^.]*.|G(?!^))[^.]*K.
在某些部分,模式匹配:
(?:
交替|
的非捕获组^[^.]*.
字符串的开头,匹配除.
之外的任何字符,然后匹配.
|
或G(?!^)
在上一场比赛结束时(而不是开始时)断言位置
)[^.]*
可选匹配除.
之外的任何字符K.
清除匹配缓冲区匹配点(待删除)
Regex演示|R演示
gsub("(?:^[^.]*\.|\G(?!^))[^.]*\K\.", "", "59.34343.23", perl=T)
输出
[1] "59.3434323"