2017-10-18 34 views
2

如何匹配年份,以便下面的示例具有一般性。正则表达式:从多个匹配中提取括号中的数字

a <- '"You Are There" (1953) {The Death of Socrates (399 B.C.) (#1.14)}' 
b <- 'Þegar það gerist (1998/I) (TV)' 

我试过了以下,但没有获得最大的成功。我认为它做的是去找到一个(然后它会创建一个数字组,然后是任何字符,直到它遇到一个)。如果有几场比赛,我想提取第一组。

任何建议我去哪里错了?我一直在做这个。

+0

那么,预期的匹配是“1953”还是“1998”?尝试'sub(“^。*?\\((\\ d {4})[^)] * \\)。*”,“\\ 1”,a)' –

+0

是的,抱歉没有指出。 –

回答

1

你的模式包含.+部分匹配尽可能多的一个或多个字符,最好你的模式可以从传入的字符串中抓取最后4个数字块。

您可以使用

^.*?\((\d{4})(?:/[^)]*)?\).* 

\1更换,只保留4位数字。见the regex demo

详细

  • ^ - 串
  • 开始
  • .*? - 任何0+字符尽可能少
  • \( - 一个(
  • (\d{4}) - 第1组:四位数字
  • (?: - 可选非c的开始apturing组
    • / - 一个/
    • [^)]* - 比)
  • )?其他任何0+字符 - 一个)(OPTIONAL,可被省略)
  • - 组
  • \)的端
  • .* - 字符串的其余部分。

R demo

a <- c('"You Are There" (1953) {The Death of Socrates (399 B.C.) (#1.14)}', 'Þegar það gerist (1998/I) (TV)', 'Johannes Passion, BWV. 245 (1725 Version) (1996) (V)') 
sub("^.*?\\((\\d{4})(?:/[^)]*)?\\).*", "\\1", a) 
# => [1] "1953" "1998" "1996" 

另一个基础R溶液是(后4个位数匹配:

regmatches(a, regexpr("\\(\\K\\d{4}(?=(?:/[^)]*)?\\))", a, perl=TRUE)) 
# => [1] "1953" "1998" "1996" 

\(\K\d{4}模式匹配(,然后将其滴由于\K匹配重置操作员,然后看到一个(?=(?:/[^)]*)?\\))确保有一个可选/ + 0 + ch除)之外,然后是)。请注意,regexpr仅提取第一个匹配项。

+0

谢谢,这是诀窍。我会在5分钟内检查答案。 –

+0

有没有办法在'Johannes Passion,BWV中捕捉正确的一年? 245(1725版)(1996)(V)'也?这里它捕捉的是“1725”而不是1996. –

+0

然后你应该更具体地了解这个模式。 * a(然后它会创建一组数字,然后是任何角色,直到遇到a)*不包括这一个。 –

2

你可以使用

library(stringr) 

strings <- c('"You Are There" (1953) {The Death of Socrates (399 B.C.) (#1.14)}', 'Þegar það gerist (1998/I) (TV)') 

years <- str_match(strings, "\\((\\d+(?: B\\.C\\.)?)")[,2] 
years 
# [1] "1953" "1998" 

这里的表达是

\(    # (
(\d+    # capture 1+ digits 
    (?: B\.C\.)? # B.C. eventually 
) 

注意反斜杠需要R进行转义。

+0

如果您想定义时代,那么也可以添加一个'A.D.'选项。 –

+0

@WiktorStribiżew:从你对问题的评论中可以看出,OP可能还不清楚真正需要什么,所以我保持原样。 – Jan