Regex в R: Как извлечь цитаты из рукописи - PullRequest
1 голос
/ 13 марта 2020

Я хотел бы извлечь цитаты как можно более точно и исчерпывающе из рукописи, используя регулярное выражение в R (поэтому мне не нужно делать это вручную). Возможно, наиболее определяющей чертой цитат является совпадение имени автора, идентифицируемого через заглавную букву, с которой оно начинается, а также год, указанный в скобках, например, Name (2020). Но существует множество вариантов этого базового c паттерна.

Вот пример текста, в котором, как мы надеемся, по крайней мере почти полный перечень реальных вариантов и фальшивых вариантов (таких как круглые скобки с менее чем четырьмя числами) цитат в рукописях:

samp <- c("Irony closely co-occurs with laughter (Norrick 2003). Blahblah
          concordances of laughter episodes, a method used by Partington (2007)
          Written Academic Language Corpus (T2K-SWAL) and adopting a Searlian 
          framework, McAllister (2015). For example, the Narrative Corpus 
          (Rühlemann & O’Donnell 2012) blahblah (MICASE), which blah
          and also Author (forthcoming) and blahblah Peter & Paul (in preparation)
          for some speech acts (cf. Maynard & Leicher 2007) blahblah
          most frequent ones in English (Carter et al. 2000: 179).blah
          include evaluative prosody (e.g., Partington 2015), vagueness (O’Keeffe 2004), 
          and deixis (e.g., Rühlemann & O’Donnell 2012). blahblah

          7 Brian:  °E:rm yeah° 
          8             (1.7)
          9 UNK:    ( )
          utterance made by a non-present speaker:
          (3)    
          I mean I've been in two shops blah most influential has been Searle’s (1975)
          and Xyz et al.'s (1999) taxonomy; (see also Kok 2017; Sperber & Wilson 1986)

          7 Ena:    and I'd always been sorry that my dad 
          8     >my dad< never <<taught us ^you know>>
          (0.5)
          9 Alan:   I’ve been trying to learn it, but I haven't got very far
          (BNC KB0: 218-223; corrected transcription)")

Регулярное выражение, которое я пробовал до сих пор, таково:

str_extract_all(samp, "([A-Z][a-z].*)?\\(\\w.*[^A-Z)]\\)")

Но соответствие далеко не идеально; несовершенные совпадения комментируются в выводе:

[[1]]
 [1] "Irony closely co-occurs with laughter (Norrick 2003)" # only "(Norrick 2003)" should match                 
 [2] "Partington (2007)"                                                       
 [3] "McAllister (2015)"                                                       
 [4] "(Rühlemann & O’Donnell 2012)"                                            
 [5] "Author (forthcoming) and blahblah Peter & Paul (in preparation)" #  should be 2 matches: "Author (forthcoming)" and "Peter & Paul (in preparation)"       
 [6] "(cf. Maynard & Leicher 2007)"                                            
 [7] "English (Carter et al. 2000: 179)"                                   
 [8] "(e.g., Partington 2015), vagueness (O’Keeffe 2004)"   # should be 2 matches: "(e.g., Partington 2015)" and "(O’Keeffe 2004)"                 
 [9] "(e.g., Rühlemann & O’Donnell 2012)"                                      
[10] "(1.7)"                       # should not match                                       
[11] "Searle’s (1975)"                                                         
[12] "Xyz et al.'s (1999) taxonomy; (see also Kok 2017; Sperber & Wilson 1986)" # should be two matches: "Xyz et al.'s (1999)" and "(see also Kok 2017; Sperber & Wilson 1986)"
[13] "(0.5)"      # should not match                                                             
[14] "(BNC KB0: 218-223; corrected transcription)" # should not match

Помощь в том, как улучшить регулярное выражение, очень ценится!

1 Ответ

0 голосов
/ 13 марта 2020

Вот мое собственное решение. Регулярное выражение действительно громоздко, но оно работает - не только для небольшого образца в вопросе, но и для больших реальных рукописей.

ШАГ 1 : загрузить рукопись и вставить ее в один строка символов:

ms <- paste0(ms, collapse = " ")

ШАГ 2 : определить шаблоны для типов ссылок:

Шаблон 1 : сопоставить цитаты, полностью заключенные в скобки, например, "(Kok 2017 et c.)":

p_1 <- "\\((Mc|O’)?[A-Za-zé][^)]*\\d{4}\\)"

Pattern 2 : совпадение цитат, где только год et c. заключен в круглые скобки, например, "Kok (2017 et c.)":

p_2 <- "(Mc|O’)?[A-Z][a-zé]+\\b\\s\\(\\d{4}(: \\d+)?\\)"

Шаблон 3 : сопоставить цитаты, где за именем следует знак перед скобками, например, "Kok et al. (2017: 1-12)":

p_3 <- "(Mc|O’)?[A-Z][a-zé]+(\\set al\\.)?(’s)?\\s\\(\\d{4}(: \\d+)?\\)"

Шаблон 4 : сопоставить цитаты с двумя именами перед круглыми скобками, например, "Kok & Kik's (2017) : 1-12) ":

p_4 <- "(Mc|O’)?[A-Z][a-zé]+\\b\\s&\\s(Mc|O’)?[A-Z][a-zé]+\\b(’s)?\\s\\(\\d{4}(: \\d+)?\\)"

Шаблон 5 : сопоставить цитаты с двумя именами, заключенными в скобки, например," (Kok & Kik 2017: 1-12) ":

p_5 <- "\\((Mc|O’)?[A-Z][a-zé]+\\b\\s&\\s(Mc|O’)?[A-Z][a-zé]+\\b\\s\\d{4}(: \\d+)?\\)"

Шаблон 6 : сопоставить цитаты, заключенные в круглые скобки и начинающиеся с содержимого, например, "(например, Kok & Kik 2017: 1-12)":

p_6 <- "\\((cf\\.\\s|e\\.g\\.,\\s)?(Mc|O’)?[A-Z][a-zé]+(\\set al\\.)?\\s\\d{4}(: \\d+)?\\)"

Образец 7 : сопоставить множественные цитаты в скобках "(ср. Kik & Kok's 2018; Pit 2008; 23; Джо 2017)":

p_7 <- "\\((cf\\.|e\\.g\\.,\\s)?(Mc|O’)?[A-Z][a-z][^)]*\\d{4}(: \\d+)?;(\\scf\\. also)?\\s(Mc|O’)?[A-Z][a-z][^)]*\\d{4}(: \\d+)?\\)"

Образец 8 : сопоставлять цитаты в квадратных скобках, например, "(но см. Kik & Kok's [2018]; см. Также [Pet 2008: 23])":

p_8 <- "(Mc|O’)?[A-Z][a-zé]+\\b\\s&\\s(Mc|O’)?[A-Z][a-zé]+\\b(’s)?\\s\\[\\d{4}(: \\d+)?\\]|\\[(Mc|O’)?[A-Z][a-zé]+\\b\\s\\d{4}(: \\d+)?\\]"

STEP 3 : объединить шаблоны и применить их к рукописи:

Объединить:

allpatterns <- paste(c(p_1,p_2,p_3,p_4,p_5,p_6,p_7, p_8), collapse="|")

Извлечь с помощью * 105 9 *:

str_extract_all(ms, allpatterns)

ШАГ 4 : результат постобработки

Сохранить:

cit <- str_extract_all(ms, allpatterns)

Разделить несколько цитат, например, " (A 2000; B 1999; ...) ":

cit_split <- unlist(str_split(unlist(cit), ";\\s"))

Очистить:

cit_clean <- gsub("\\(|\\)|\\[|\\]|:\\s\\d+(-\\d+)?|(e\\.g\\.,|see also|cf.(\\salso)?)\\s|'s|’s|;", "", cit_split)

Упорядочить уникальные цитаты в алфавитном порядке:

cit_unique <- sort(unique(cit_clean))

Вот и все . Теперь у вас должен быть упорядоченный список всех ссылок в рукописи!

Отказ от ответственности : Шаблоны, определенные выше, охватывают многие форматы цитирования, но не все! Не стесняйтесь адаптировать код к своему нужды и непредвиденные обстоятельства.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...