【问题标题】:Get last four words per column in R获取R中每列的最后四个单词
【发布时间】:2015-03-31 18:23:00
【问题描述】:

我有一个包含多列的数据集,其中之一 (d$leftContext) 包含以下字符串:

Eens zien of je binnen een paar jaar , wanneer er hier misschien een 
Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die 
Die 
Die 
Als de 

对于其中的每一个,我只想返回最后四个单词。我首先想用正则表达式来实现这一点,但我很确定当字符串短于四个单词时这将不起作用(后三种情况就是这种情况)。此外,当单词之间存在除 spacew 以外的任何其他字符时(如第二行的情况),我提出的正则表达式将不起作用。查看我的正则表达式 here 的示例。

.*(?=(\b\w+\s){4}$)

那么,我怎样才能去掉 R 中的最后四个单词(它们之间的所有内容)?

对于上面显示的块,结果看起来像(如果没有足够的存在,保留最后四个单词或更少):

er hier misschien een
westen te smijten...Die 
Die 
Die 
Als de 

【问题讨论】:

  • 如果需要最后4个字sapply(strsplit(d1[,1], ' '), tail,4)
  • 首先要意识到的是,正则表达式和 R 都使用反斜杠作为转义字符,因此在使用 R 的系统 PCRE 库的包装器创建模式字符串时,您需要将“\”加倍。
  • @BondedDust 我在 JavaScript 中使用 Regex 有经验,但我仍在尝试找出应该在 R 中转义的字符...似乎无法在网上找到任何列表!
  • @BramVanroy 您能否更新预期结果以避免混淆
  • @akrun 完成。我认为您的解决方案会起作用,只是在第二种情况下不起作用。例如,如果您将4 更改为1,则输出将为smijten...Die 而不仅仅是Die

标签: regex r


【解决方案1】:

首先要意识到正则表达式和 R 都使用反斜杠作为转义字符,因此在创建模式字符串时需要将“\”加倍。这将返回字符类项目" "",""." 列表的4 个单词和嵌入的分隔符。唯一要转义的字符是反斜杠。

> sub( patt='(.+)(([ ,.]+\\w+){4})[ ]?$', repl='\\2', Lines)
[1] " er hier misschien een"   " westen te smijten...Die" "Die "  
[4] "Die "                     "Als de"                  

实际上并没有匹配最后三个,因为它们实际上没有 4 个分隔符模式。我需要输入最后的 "[ ]? 因为有几行复制的尾随空格弄乱了我的匹配。

>dput(Lines)
c("Eens zien of je binnen een paar jaar , wanneer er hier misschien een ", 
"Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die ", 
"Die ", "Die ", "Als de")

【讨论】:

  • 使用[ ]\\s有什么明显的区别吗?
  • 我不知道,反正专门用于比较。概括字符类版本以允许其他文本分隔符(例如 ".""," 以及我认为您要求的“/”)会更容易。 R ?regex-page 表示 \\s 的模式是:"tab, newline, vertical tab, form feed, carriage return, space and possibly other locale-dependent characters."
  • 您可以在?Quotes 帮助页面上找到 R 识别的一些“空间”类成员的文本表示。
【解决方案2】:

这样就可以了:

df <- data.frame(leftContext=c('Eens zien of je binnen een paar jaar , wanneer er hier misschien een','Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die','Die','Die','Als de'), stringsAsFactors=F );
df$leftContext;
## [1] "Eens zien of je binnen een paar jaar , wanneer er hier misschien een"
## [2] "Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die"
## [3] "Die"
## [4] "Die"
## [5] "Als de"
sub('(\\b\\w+\\b\\W*){1,4}$','',df$leftContext);
## [1] "Eens zien of je binnen een paar jaar , wanneer "
## [2] "Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het "
## [3] ""
## [4] ""
## [5] ""

关键是变量绑定{1,4}的使用;这确保了如果少于四个单词,仍然会删除 1:3 的尾随单词。此外,非空白分隔符很容易被\W 覆盖,它匹配任何非单词字符。

编辑:抱歉,OP 说的是“return”,然后是“strip off”,而我用“strip off”表示删除。

我一直在尝试修改我的正则表达式来满足要求,但值得注意的是,在我看来,R 的正则表达式实现,至少关于在正则表达式中有变量绑定时扩展替换字符串中的捕获组, 被打破。在这种情况下,替换字符串中的\1\2 等无法正确展开。

为了解决这个问题,我想出了一个技巧,它使用substr() 来提取您想要的输入字符串的尾随部分:

df <- data.frame(leftContext=c('Eens zien of je binnen een paar jaar , wanneer er hier misschien een','Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die','Die','Die','Als de'), stringsAsFactors=F );
df$leftContext;
## [1] "Eens zien of je binnen een paar jaar , wanneer er hier misschien een"
## [2] "Ik zou denken van wel , eens deze kerel verdwenen zullen er nog erger aan de macht komen , mensen , crimineel krankzinnig , en fanatiek godsdienstig genoeg om met atoombommen naar het westen te smijten...Die"
## [3] "Die"
## [4] "Die"
## [5] "Als de"
substr(df$leftContext,nchar(sub('(\\b\\w+\\b\\W*){1,4}$','',df$leftContext))+1,nchar(df$leftContext));
## [1] "er hier misschien een"   "westen te smijten...Die" "Die"                     "Die"                     "Als de"

【讨论】:

  • 你能把所有单词\\w+ 匹配到数组中并取最后1-4 个单词吗?
  • @MaxZoom 这正是 bgoldst 的正则表达式所做的,但你不能只是“接受”它。你必须用一些东西来代替你的渔获物。你也不能改变周围的东西,因为前瞻不能得到量词。
  • 我怀疑您需要转义“替换”参数中的反斜杠。请参阅我的示例代码。
  • @BondedDust,我在测试代码时确实转义了反斜杠。我只是没有在答案的讨论文本中显示转义,因为我试图强调正则表达式实现使用的实际文本,而不是原始用户输入。 R 的正则表达式实现中似乎肯定存在错误。您的正则表达式有效的原​​因是它不包含变量绑定。
  • 我只使用了带有 R 包装器的正则表达式。在 R 中,这是一个字符:"\\"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-08
  • 1970-01-01
  • 2021-04-29
  • 1970-01-01
相关资源
最近更新 更多