在 R 中仅提取一个已知字符串之间的字符串

Extract strings between only one known string in R

我想在另外两个字符串之间提取一个字符串。一个字符串是回车 return,而另一个是几乎相似字符的变体:

dput(head(decisions$Title))
c("Zinaida Shumilina et al. v. Belarus                    \r\n                    
CCPR/C/120/D/2142/2012", 
"K.E.R. vs. Canada                    \r\n                    
CCPR/C/120/D/2196/2012", 
"Lounis Khelifati v Algeria                    \r\n                    
CCPR/C/120/D/2267/2013", 
"Hibaq Said Hash v. Denmark                    \r\n                    
CCPR/C/120/D/2470/2014", 
"Anton Batanov v. Russian Federation                    \r\n                    
CCPR/C/120/D/2532/2015", 
"S. Z. v. Denmark                    \r\n                    
CCPR/C/120/D/2625/2015"
)

我基本上想提取 "v." 和马车 return \r 之间的国家/地区名称。但是,"v." 有时是 "v"、"vs."、"vs" 和 "v:"。

根据相关 SO 问题的答案,我尝试了以下操作:

res <- str_match(decisions$Title, "(v\.|vs\.|v)(.*?)\r")
res[,3]

不幸的是,这并没有得到所有的变化,或者在某些情况下,当试图从 "Navruz Tahirovich Nasyrlayev v. Turkmenistan CCPR/C/117/D/2219/2012" 中提取国家名称时,它 returns 数据如 "ruz Tahirovich Nasyrlayev v. Turkmenistan"。

还有其他方法可以实现吗?

我们可以使用sub来匹配字符(.*)直到一个单词边界(\b)后跟'v'后跟s或.,一个或多个空格 (\s+) 并捕获不是 \r ([^\r]+) 的字符及其后的其他字符。在替换中,使用捕获组的反向引用 (\2) 并使用 trimws

删除尾随空格
trimws(sub(".*\bv(s*\.*)\s+([^\r]+)\s*\r.*", "\2", v1))
#[1] "Belarus"            "Canada"             "Algeria"   
#[4] "Denmark"            "Russian Federation" "Denmark"           

您可以使用

trimws(str_match(decisions$Title, "\bv(?:s?\.|:)?\s*(.*)")[,2])

regex demo。请注意,trimws 将删除多余的前导和尾随空白字符。

图案详情

  • \b - 单词边界
  • v - 一个 v 字符
  • (?:s?\.|:)? - 可选地匹配可选的 s 后跟 .: char
  • \s* - 0+ 个空白字符
  • (.*) - 第 1 组:除换行符之外的任何 0+ 个字符(请注意,您不必担心 . 是否匹配 CR 符号(在 TRE 正则表达式中在 sub 中使用 . 也匹配 LF 符号)因为 trimws 无论如何都会删除 leading/trailing 空格)。

在 R 中测试:

> df<-c("Zinaida Shumilina et al. v. Belarus                    \r\n                    
+ CCPR/C/120/D/2142/2012", 
+ "K.E.R. vs. Canada                    \r\n                    
+ CCPR/C/120/D/2196/2012", 
+ "Lounis Khelifati v Algeria                    \r\n                    
+ CCPR/C/120/D/2267/2013", 
+ "Hibaq Said Hash v. Denmark                    \r\n                    
+ CCPR/C/120/D/2470/2014", 
+ "Anton Batanov v. Russian Federation                    \r\n                    
+ CCPR/C/120/D/2532/2015", 
+ "S. Z. v. Denmark                    \r\n                    
+ CCPR/C/120/D/2625/2015"
+ )

> trimws(str_match(df, "\bv(?:s?\.|:)?\s*(.*)")[,2])
[1] "Belarus"            "Canada"             "Algeria"           
[4] "Denmark"            "Russian Federation" "Denmark"           
> 

您还可以在 "v"

之前添加单词边界
str_match(decisions$Title, "(\b)(v\.|vs\.|v)(.*?)\r")