使用 R 删除字符串中除第一个点以外的所有点

问题描述 投票:0回答:5

我在某些显示“59.34343.23”等数字的数字中存在一些错误。我知道第一个点是正确的,但第二个点(或第一个点之后的任何点)应该删除。我怎样才能删除这些?

我尝试在 R 中使用 gsub:

gsub("(?<=\\..*)\\.", "", "59.34343.23", perl=T)

gsub("(?<!^[^.]*)\\.", "", "59.34343.23", perl=T)

但是它会出现以下错误“无效的正则表达式”。但我一直在正则表达式测试器中尝试相同的代码并且它有效。 我在这里犯了什么错误?

r regex gsub
5个回答
4
投票

你可以使用

gsub("^([^.]*\\.)|\\.", "\\1", "59.34343.23")
gsub("^([^.]*\\.)|\\.", "\\1", "59.34343.23", perl=TRUE)

查看 R 在线演示regex 演示

详情

  • ^([^.]*\.)
    - 捕获组 1(在替换模式中称为
    \1
    ):字符串开头的任何零个或多个字符,然后是
    .
    字符(字符串中的第一个)
  • |
    - 或
  • \.
    - 字符串中的任何其他点。

由于替换

\1
指的是第 1 组,而第 1 组仅包含第一个点之前的文本匹配后的值,因此替换要么是这部分文本,要么是空字符串(即第二个和所有后续出现的点都将被删除)。


1
投票

我们可能会使用

gsub("^[^.]+\\.(*SKIP)(*FAIL)|\\.", "", str1, perl = TRUE)
[1] "59.3434323"

数据

str1 <-  "59.34343.23"

1
投票

您尝试的模式不匹配,因为lookbehind中存在无限量词

(?<=\\..*)
不受支持。

使用

\G
的另一种变体在第一个点之后获得连续匹配:

(?:^[^.]*\.|\G(?!^))[^.]*\K\.

部分模式匹配:

  • (?:
    用于交替的非捕获组
    |
    • ^[^.]*\.
      字符串开头,匹配除
      .
      之外的任何字符,然后匹配
      .
    • |
      或者
    • \G(?!^)
      断言上一场比赛结束时的位置(而不是开始时)
  • )[^.]*
    可选择匹配除
    .
  • 之外的任何字符
  • \K\.
    清除匹配缓冲区并匹配点(要删除)

正则表达式演示 | R 演示

gsub("(?:^[^.]*\\.|\\G(?!^))[^.]*\\K\\.", "", "59.34343.23", perl=T)

输出

[1] "59.3434323"

0
投票

始终可以选择仅写回该行中的第一个点。
主要功能是消耗其他点,但不将其写回。
效果是删除尾随点。

下面使用分支重置来完成目标(Perl 模式)。

(?m)(?|(^[^.\n]*\.)|()\.+)

更换

$1

https://regex101.com/r/cHcu4j/1

 (?m)
 (?|
    ( ^ [^.\n]* \. )              # (1)
  | ( )                           # (1)
    \.+ 
 )

0
投票

通过指定

perl = TRUE
,您可以将以下正则表达式的匹配项转换为空字符串:

^[^.]*\.\K|(?!^)\G[^.]*\K\.

演示

如果您不熟悉

\K
\G
,请将鼠标悬停在链接的正则表达式中,查看其效果的说明。

© www.soinside.com 2019 - 2024. All rights reserved.