Search code examples
regexquanteda

How to define optional element in regex pattern with quanteda's kwic?


I am struggling to 'translate' a regex expression from stringi/stringr to quanteda's kwic function.

How can I get all instances of "Jane Mayer", regardless of whether she has a middle name or not. Note that I don't have a list of all existing middle names in the data. So defining multiple patterns (one for each middle name) wouldn't be possible.

Many thanks!

library(quanteda)
library(tidyverse)
txt <- c("this is Jane Alexandra Mayer", 
         "this is Jane Mayer",
         "this is Jane Eli Mayer", 
         "this is Jane Burger")

txt_token <- tokens(txt)

my_pattern <- c("Jane .* Mayer")
kwic(txt_token, pattern=phrase(my_pattern), valuetype = "regex")
#> Keyword-in-context with 2 matches.                                               
#>  [text1, 3:5] this is | Jane Alexandra Mayer | 
#>  [text3, 3:5] this is |    Jane Eli Mayer    |

my_pattern <- c("Jane .? Mayer")
kwic(txt_token, pattern=phrase(my_pattern), valuetype = "regex")
#> Keyword-in-context with 2 matches.                                               
#>  [text1, 3:5] this is | Jane Alexandra Mayer | 
#>  [text3, 3:5] this is |    Jane Eli Mayer    |

my_pattern <- c("Jane.* Mayer")
kwic(txt_token, pattern=phrase(my_pattern), valuetype = "regex")
#> Keyword-in-context with 1 match.                                     
#>  [text2, 3:4] this is | Jane Mayer |

my_pattern <- c("Jane . Mayer")
kwic(txt_token, pattern=phrase(my_pattern), valuetype = "regex")
#> Keyword-in-context with 2 matches.                                               
#>  [text1, 3:5] this is | Jane Alexandra Mayer | 
#>  [text3, 3:5] this is |    Jane Eli Mayer    |

With stringr I'll would simply use:

str_extract(txt, regex("Jane.* Mayer"))
#> [1] "Jane Alexandra Mayer" "Jane Mayer"           "Jane Eli Mayer"      
#> [4] NA
```

<sup>Created on 2021-11-28 by the [reprex package](https://reprex.tidyverse.org) (v2.0.1)</sup>

Solution

  • It seems you need to pass another pattern to match exactly Jane Mayer:

    kwic(txt_token, pattern=phrase(c("Jane .* Mayer", "Jane Mayer")), valuetype = "regex")
    # => Keyword-in-context with 3 matches.                                               
    #    [text1, 3:5] this is | Jane Alexandra Mayer | 
    #    [text2, 3:4] this is |      Jane Mayer      | 
    #    [text3, 3:5] this is |    Jane Eli Mayer    |