Regex 删除字符的最后一次出现

Regex 删除字符的最后一次出现,regex,r,Regex,R,海报希望使用正则表达式(而不是strsplit)删除字符串的最后一个句点的一种方法。我试图这样做,但没有成功 N <- c("59.22.07", "58.01.32", "57.26.49") #my attempts: gsub("(!?\\.)", "", N) gsub("([\\.]?!)", "", N) 您需要这个正则表达式:- [.](?=[^.]*$) 并将其替换为空字符串 所以,应该是这样的:- gsub("[.](?=[^.]*$)","",N,perl = T

海报希望使用正则表达式(而不是
strsplit
)删除字符串的最后一个句点的一种方法。我试图这样做,但没有成功

N <- c("59.22.07", "58.01.32", "57.26.49")

#my attempts:
gsub("(!?\\.)", "", N)
gsub("([\\.]?!)", "", N)
您需要这个正则表达式:-

[.](?=[^.]*$)
并将其替换为空字符串

所以,应该是这样的:-

gsub("[.](?=[^.]*$)","",N,perl = TRUE)
解释:-

[.]         // Match a dot
(?=         // Followed by
    [^.]    // Any character that is not a dot.
     *      // with 0 or more repetition
     $      // Till the end. So, there should not be any dot after the dot we match.
)  

因此,只要在前瞻中匹配了一个
点(.)
,匹配就失败了,因为在当前点之后的某个地方有一个
,模式是匹配的。

我对我的正则表达式很懒,但这是可行的:

gsub("(*)(.)([0-9]+$)","\\1\\3",N)

我倾向于采取与标准相反的方法。我没有将“.”替换为零长度字符串,而是解析两边的两个部分。

也许这样读起来更好一些:

gsub("(.*)\\.(.*)", "\\1\\2", N)
[1] "59.2207" "58.0132" "57.2649"
因为它是贪婪的,所以第一个
(.*)
将匹配到最后一个
的所有内容,并将其存储在
\\1
中。第二个
(.*)
将匹配最后一个
之后的所有内容,并将其存储在
\\2

这是一个一般性的答案,即您可以用您选择的任何字符替换
\\.
,以删除该字符最后出现的位置。这是唯一一个替代做

你甚至可以:

gsub("(.*)\\.", "\\1", N)

我相信您现在已经知道了这一点,因为您在软件包中使用了
stringi
,但您可以简单地做到这一点

N <- c("59.22.07", "58.01.32", "57.26.49")

stringi::stri_replace_last_fixed(N, ".", "")
# [1] "59.2207" "58.0132" "57.2649"

N如果在末尾包含组,则可以使用
gsub
执行此操作
gsub('\\.([0-9]+)$,'\\1',N)
你的第一个函数几乎可以用
sub
很好地工作。谢谢你,贾斯汀,但这是错误的:)可能重复的@Bohemian人非常擅长正则表达式,他们通常对什么是重复的定义比我要宽松得多。我根本不知道如何用这个问题的答案来解决R.@Arun中的这个问题。。对不起,
$
有点放错地方了。现在修好了。@Justin。嗯,这不是要求的吗?我想,OP只想替换最后一个
句点
,而不是它后面的完整字符串。@Arun。。我不知道这些函数和语言
r
,所以我不能发表评论。我刚刚发布了一个有效的正则表达式,它将与你的函数一起工作。我有意将标题改为字符而不是句号,以使这个问题对其他人更具普遍性。我认为这种反应最能概括为多种情况+1@TylerRinker:两种解决方案应是等效的。在flodel的解决方案中,除了新行以外,任何字符都有一个小的不同,但是它可以很容易地修复。非常好的解释flodel。谢谢你的回复。我检查了罗希特·贾因,因为我认为他的反应更能概括到更多不同的情况。对于这种特殊情况,您的回答是“当场+1”。Stringi非常棒,而且越来越令人敬畏。也感谢您添加此方法+1.
N <- c("59.22.07", "58.01.32", "57.26.49")

stringi::stri_replace_last_fixed(N, ".", "")
# [1] "59.2207" "58.0132" "57.2649"