【问题标题】:Parse text by uppercase in R在R中按大写解析文本
【发布时间】:2015-06-04 05:06:45
【问题描述】:

我有许多具有以下基本组成的大型文本文件:

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)]

期望的结果是这样的数据框或表格:

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

我无法将每条消息“链接”到其作者。

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

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

任何帮助表示赞赏。

【问题讨论】:

  • 最后一个问题,可以在:upper:后面加一个分隔符{2},这样一排至少要有两个大写字母(至少可以避免“I”的问题。

标签: r text text-mining uppercase


【解决方案1】:

这是使用 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

【讨论】:

  • 我相信这里的正则表达式向导之一会有更简洁的方法。
  • {2,1000} 有点脏
  • [A-Z]{2,1000} 可能被替换为:[A-Z][A-Z]+,这将允许两个最多为无限的人员标识符。
  • @petermeissner 你能举个例子吗?在 R 中使用 stri_split_regexstrsplit 表示无效模式
  • 查看我的答案作为示例(您可以将 [[:upper:]] 替换为 [A-Z]
【解决方案2】:

基本方法

1) 要获取文本,我将按照 Tyler Rinkers 的方法将文本按一个或多个 (+) 的序列拆分,仅大写字母 ([[:upper:]]),可能还包含空格和冒号 (@987654323 @):"[[:upper:]]+[ [:upper:]:]+"

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

字符串

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

字符串i

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

... 在特殊字符的情况下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-10
    • 2023-02-18
    • 2023-03-15
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    相关资源
    最近更新 更多