在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
...如果是特殊字符。
我有很多基本组成如下的大文本文件:
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
...如果是特殊字符。