Проблема извлечения строки из символьного вектора - PullRequest
1 голос
/ 09 февраля 2020

У меня проблемы с извлечением определенных совпадений из моего вектора символов, который я назвал классами, используя библиотеку stringr:

classes = read_lines("https://statistics.ucdavis.edu/courses/descriptions-undergrad") %>%
  str_flatten()

Небольшой фрагмент classes:

...collaborative data analysis; complete case study review and team data analysis project. 
Effective: 2019 Fall Quarter.</p><h2>STA 190X—Seminar (1-2)</h2><p>Seminar—1-2 hour(s). Prerequisite(s):
STA 013 or STA 013Y or STA 032 or STA 100 or STA 103. In-depth examination of a special topic in a small 
group setting. Effective: 2018 Spring Quarter.</p><h2>STA 192—Internship in Statistics (1-12)</h2>
<p>Internship—3-36 hour(s); Term Paper...

Я ясно вижу, что слово "STA 190X" находится в моем векторе, но я не могу его извлечь:

>str_detect(classes, "STA 190X")
[1] FALSE

>str_extract_all(classes, "STA 190X")
[[1]]
character(0)

Но если я скопирую и вставлю раздел прямо в функцию, это работает:

> str_detect("</p><h2>STA 190X—Seminar (1-2)</h2>", "STA 190X")
[1] TRUE

> str_extract_all("</p><h2>STA 190X—Seminar (1-2)</h2>", "STA 190X")
[[1]]
[1] "STA 190X"

Кто-нибудь знает, почему это так?

Ответы [ 3 ]

1 голос
/ 09 февраля 2020

Простое решение:

Вам нужно только немного адаптировать свое регулярное выражение, чтобы соответствовать не только пробелу, но и всему, что не является буквой или числом:

str_detect(classes, "STA[^A-z0-9]190X")  
[1] TRUE

Объяснение :

Это самая странная вещь:

match_position <- gregexpr("STA[^ ]*190X", classes)[[1]][1]
substr(classes, match_position - 10, match_position + 17)

Приведенный выше код возвращает совпадение чего-то, что выглядит как строка 'STA 190X', но не .

"r.</p><h2>STA 190X—Seminar ("

Этого не может быть, потому что между STA и 190X не может быть пробела. Если бы был пробел, gregexpr не поймал бы его (STA[^ ]*190X соответствует всему, что не имеет пробел (ы) между STA и 190X)

Редактировать:

Сгущение сюжета:

grepl("STA[^[:punct:]]*190X", classes)

Возвращает нет соответствия, что, я думаю, означает, что загадочный персонаж является одним из:

[: punct:]

Знаки пунктуации:! "# $% & '() * +, -. /:; <=>? @ [\] ^ _` {|} ~.

1 голос
/ 10 февраля 2020

Пробелы, похоже, проблема. Попробуйте использовать \\s для пробелов, и это должно работать.

readr::read_lines("https://statistics.ucdavis.edu/courses/descriptions-undergrad") %>%
    stringr::str_flatten() %>%
    stringr::str_extract("STA\\s190X")

#[1] "STA 190X"
1 голос
/ 09 февраля 2020

Мы можем выполнить обработку с помощью rvest и извлечь правильные «узлы»

library(rvest)
library(stringr)
library(magrittr)
read_html("https://statistics.ucdavis.edu/courses/descriptions-undergrad") %>%
       html_nodes("h2") %>%
       html_text() %>% 
       str_c(collapse = ' ') %>% 
       str_extract(., "STA 190X")
#[1] "STA 190X"
...