在R中按大写解析文本

Parse text by uppercase in R

我有很多基本组成如下的大文本文件:

text<-"this is a speech text. FIRST PERSON: hi all, thank you for coming. SECOND PERSON: thank you for inviting us"

如您所见,它由以下部分组成:1) 随机文本,2) 大写人物,3) 语音。

我已经成功地在一个列表中分隔了所有使用的单词:

textw<-unlist(strsplit(text," "))

然后我找到所有大写单词的位置:

grep(pattern = "^[[:upper:]]*$",x = textw)

并且我已经将人名分离成一个向量;

upperv<-textw[grep(pattern = "^[[:upper:]]*$",x = textw)]

期望的结果将是一个数据框或 table 像这样:

Result<-data.frame(person=c(" ","FIRST PERSON","SECOND PERSON"),
         message=c("this is a speech test.","hi all, thank you for coming.","thank you for inviting us"))

Result
         person                       message
1                      this is a speech test.
2  FIRST PERSON hi all, thank you for coming.
3 SECOND PERSON     thank you for inviting us

我遇到了问题 "linking" 每条发给其作者的消息。

另请注意:有些大写单词不是作者,例如 "I"。如何仅在 2 个或更多大写单词彼此相邻的情况下指定分隔符?

换句话说,如果位置 2 和 3 是大写,则将位置 4 到下一次出现双大写的所有内容作为消息放置。

感谢任何帮助。

这是使用 stringi 包的一种方法:

text <- "this is a speech text. FIRST PERSON: hi all, thank you for coming. SECOND PERSON: thank you for inviting us"

library(stringi)
txt <- unlist(stri_split_regex(text, "(?<![A-Z]{2,1000})\s+(?=[A-Z]{2,1000})"))

data.frame(
    person = stri_extract_first_regex(txt, "[A-Z ]+(?=(:\s))"),
    message = stri_replace_first_regex(txt, "[A-Z ]+:\s+", "")
)


##          person                       message
## 1          <NA>        this is a speech text.
## 2  FIRST PERSON hi all, thank you for coming.
## 3 SECOND PERSON     thank you for inviting us

基本方法

1) 为了获取文本,我将遵循 Tyler Rinkers 的方法,将文本拆分为一个或多个 (+) 仅大写字母 ([[:upper:]]) 的序列,这可能还需要空格和冒号 ([ [:upper:]:]):"[[:upper:]]+[ [:upper:]:]+"

2) 提取使用几乎相同的正则表达式的人(不再允许使用冒号):"[[:upper:]]+[ [:upper:]]+"(同样,基本思想是从 Tyler Rinker 那里偷来的)

stringr

require(stringr)

text <- "this is a speech text. FIRST PERSON: hi all, thank you for coming. SECOND PERSON: thank you for inviting us"

data.frame (
    person  = c( NA,
                 unlist(str_extract_all(text, "[[:upper:]]+[ [:upper:]]+"))
                ),
    message = unlist(str_split(text, "[[:upper:]]+[ [:upper:]:]+"))
    )

##          person                        message
## 1          <NA>        this is a speech text. 
## 2  FIRST PERSON hi all, thank you for coming. 
## 3 SECOND PERSON      thank you for inviting us

stringi

require(stringi)

text <- "this is a speech text. FIRST PERSON: hi all, thank you for coming. SECOND PERSON: thank you for inviting us"

data.frame (
    person  = c( NA,
                 unlist(stri_extract_all(text, regex="[[:upper:]]+[ [:upper:]]+"))
                ),
    message = unlist(stri_split(text, regex="[[:upper:]]+[ [:upper:]:]+"))
    )

##          person                        message
## 1          <NA>        this is a speech text. 
## 2  FIRST PERSON hi all, thank you for coming. 
## 3 SECOND PERSON      thank you for inviting us

提示(反映我的偏好而不是规则)

1) 我更喜欢 "[A-Z]+" 而不是 "[A-Z]{1,1000}" 因为在第一种情况下 on 不必决定什么可能实际上是一个合理的数字。

2) 我更喜欢 "[[:upper:]]" 而不是 "[A-Z]" 因为前者是这样工作的...

str_extract("Á", "[[:upper:]]")
## [1] "Á"

...而后者是这样工作的...

str_extract("Á", "[A-Z]")
## [1] NA

...如果是特殊字符。