【问题标题】:Regex doesn't capture numbers written out as words正则表达式不会捕获写成单词的数字
【发布时间】:2019-09-23 19:25:26
【问题描述】:

我正在用英语和法语查看 Oliver Twist。我发现这个网站 (https://cran.r-project.org/web/packages/tidytext/vignettes/tidytext.html) 提供了代码来应用每行文本的章节号。当我将它应用于英文文本时,它工作得很好:

library(gutenbergr)
library(dplyr)
library(tidytext)
library(stringr)
twistEN <- gutenberg_download(730)
twistEN <- twistEN[118:nrow(twistEN),]
chaptersEN <- twistEN %>%
  mutate(line = row_number(), chapter = cumsum(str_detect(text, regex("^chapter [\\divxlc]", ignore_case = TRUE)))) %>%
  ungroup()

当我查看 chaptersEN 时,我可以看到它在每一行上适当地应用了章节编号。我遇到麻烦的地方是法语文本。这是我的代码:

twistFR <- gutenberg_download(16023)
twistFR <- twistFR[123:nrow(twistFR),]
twistFR$text <- iconv(twistFR$text, "latin1", "UTF-8")
chaptersFR <- twistFR %>%
  mutate(line = row_number(), chapter = cumsum(str_detect(text, regex("^chaptitre [\\divxlc]", ignore_case = TRUE)))) %>%
  ungroup()

这里的问题是这些章节没有命名为第 1 章和第 2 章,它们被命名为 Chapitre Premier、Chapitre Deuxieme。我相信正则表达式是通过查看单词 chapter 后面的数字来找到章节编号(如果我错了,请纠正我),所以当那个数字被写成一个单词时,它不知道该怎么做。关于如何应用章节编号的任何想法?

【问题讨论】:

  • 是的,这很难。除了枚举数字单词并将其映射到实际数字之外,您有点不走运。但是,您可以仅根据递增索引假设章节编号,基本上完全避开 条信息的正则表达式。

标签: r regex tidytext project-gutenberg


【解决方案1】:

在这种情况下,匹配以大写“CHAPITRE”开头的行就足够了。

chaptersFR <- twistFR %>%
  mutate(line = row_number(), chapter = cumsum(str_detect(text, regex("^CHAPITRE")))) %>%
  ungroup()

chaptersFR %>% 
  filter(grepl("^chapitre", text, ignore.case = TRUE)) %>%
  head(5)

# A tibble: 5 x 4
  gutenberg_id text               line chapter
         <int> <chr>             <int>   <int>
1        16023 CHAPITRE PREMIER.     1       1
2        16023 CHAPITRE II         124       2
3        16023 CHAPITRE III        604       3
4        16023 CHAPITRE IV.       1006       4
5        16023 CHAPITRE V.        1333       5

chaptersFR %>% 
  filter(grepl("^chapitre", text, ignore.case = TRUE)) %>%
  tail(5)

# A tibble: 5 x 4
  gutenberg_id text                                                            line chapter
         <int> <chr>                                                          <int>   <int>
1        16023 CHAPITRE L.                                                    18443      50
2        16023 CHAPITRE LI.                                                   18973      51
3        16023 chapitre, Olivier se trouvait, à trois heures de l'après-midi, 18979      51
4        16023 CHAPITRE LII                                                   19580      52
5        16023 CHAPITRE LIII.                                                 19989      53

【讨论】:

    【解决方案2】:

    简短的回答:你写的是 chaptitre 而不是 chapitre

    你在代码中使用[\\divxlc] 部分是为了什么?
    例如:^chapitre [\\divxlc]
    ^ 表示在行首
    chapitre 仅匹配单词 chapitre(仅小写)
    空白字段匹配空格
    [\\divxlc] 部分仅匹配 '\'、'd'、'i'、'v'、'x'、'l' 或 'c'

    所以它可以匹配这些例子: chapitre dchapitre ichapitre \

    如果您希望 chapitre 开头的 c 为大写或小写,您可以使用:
    ^[cC]hapitre [\\divxlc]

    【讨论】:

    • 老实说,我从另一个站点复制了正则表达式。我唯一能想到的是它打算寻找罗马数字?
    猜你喜欢
    • 1970-01-01
    • 2022-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 1970-01-01
    • 2019-02-20
    相关资源
    最近更新 更多