R regex:从字符串中删除时间

5
我试图从一个字符字符串中删除/提取时间。逻辑是我正在获取以下内容:
  1. 必须以0-2个数字开头
  2. 必须后跟单个冒号
  3. 可以后跟冒号或句点,但不一定需要
  4. 可以后跟1到无穷大的数字(如果上一个条件成立)
这是一个MWE和我尝试过的方法。我已经接近成功,但我不想提取"6:33."而是要提取"6:33",因为冒号或逗号的出现必须后跟1个或更多数字。在这种情况下,句点是句子的结尾,而不是时间的一部分。
text.var <-  c("R uses 1:5 for 1, 2, 3, 4, 5.", 
    "At 3:00 we'll meet up and leave by 4:30:20.",
    "We'll meet at 6:33.", "He ran it in :22.34.")

pattern <- "\\(?[0-9]{0,2}\\)?\\:\\(?[0-9]{2}\\)?\\(?[:.]{0,1}\\)?\\(?[0-9]{0,}\\)?"

regmatches(text.var, gregexpr(pattern, text.var, perl = TRUE))

## [[1]]
## character(0)
## 
## [[2]]
## [1] "3:00"    "4:30:20"
## 
## [[3]]
## [1] "6:33."
## 
## [[4]]
## [1] ":22.34"

期望输出

## [[1]]
## character(0)
## 
## [[2]]
## [1] "3:00"    "4:30:20"
## 
## [[3]]
## [1] "6:33"
## 
## [[4]]
## [1] ":22.34"
2个回答

4
如果我理解正确,您可以使用以下内容来解决您的问题。
regmatches(text.var, gregexpr('\\d{0,2}:\\d{2}(?:[:.]\\d+)?', text.var, perl=T))

解释:

\d{0,2}   # digits (0-9) (between 0 and 2 times)
:         # ':'
\d{2}     # digits (0-9) (2 times)
(?:       # group, but do not capture (optional):
  [:.]    #   any character of: ':', '.'
  \d+     #   digits (0-9) (1 or more times)
)?        # end of grouping

注意: 我删除了转义括号,因为我不清楚它们一开始被使用的原因。


1
嗨 @hwnd,你也可以将其缩短为\d{0,2}:\d{2}(?:[:.]\d+)? - Federico Piazza
两种解决方案都很好,这是第一个正确的回答。比我自己写的更易读。谢谢。+1 - Tyler Rinker
1
@TylerRinker 很高兴我能再次帮到你 =) - hwnd

1
这是你想要的吗:
regmatches(text.var, gregexpr("(\\d{0,2}:\\d{2}(?:\\.\\d+)?)", text.var))

工作演示

(保留HTML)
MATCH 1
1.  [42-46] `3:00`
MATCH 2
1.  [74-78] `4:30`
MATCH 3
1.  [78-81] `:20`
MATCH 4
1.  [104-108]   `6:33`
MATCH 5
1.  [126-132]   `:22.34`

1
@TylerRinker 很好,很高兴能帮助像你这样的人。 - Federico Piazza
1
我认为它不适当地将第二个目标分割在第二个元素中。 - IRTFM
@BondedDust 我觉得我在编辑时搞砸了,我试图使用双下划线。我回到了Fede的方式(使用\\而不是\),并添加了提取R代码的代码。 - Tyler Rinker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接