基于正则表达式高亮显示DT中的单词

Meg*_*gan 5 r shiny dt

使用DT时,我希望能够突出显示所选单词。设置searchHighlight = TRUE接近我想要的设置,但这也会突出显示包含搜索的单词。例如,如果我要搜索“ on”,它也会与“ stone”匹配,突出显示中间的“ on”。

图片示例:

突出显示单词中的单词

我可以这样优化搜索选项regex = TRUE,但是不会突出显示。例如,如果我想使用“ on | in”之类的正则表达式,也是如此。

示例(包括正则表达式):

library(shiny)
library(DT)
library(data.table)

example_data <- data.table(words = c("on", "scone", "wrong", "stone"), 
                           description = c("The word on", "Scone is not on.", "Not on either", "Not here at all"))

ui = shinyUI(fluidPage(

  sidebarLayout(
    sidebarPanel(
      textInput("word_select", label = "Word to search")
      ),
    mainPanel(
      dataTableOutput("word_searched")
    )
  )
))

server = shinyServer(function(input, output, session) {

  output$word_searched <- renderDataTable({
    datatable(
      example_data, 
      options = list(searchHighlight = TRUE, 
                     search = list(regex = TRUE, 
                                   search = paste0("\\b", tolower(input$word_select), "\\b")))
    )
  })

  })

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)

DT已经通过反应式表达式对单词进行了过滤,因此所有字段都将肯定包含所选单词,但是我只是想避免用户误以为较长的单词被错误地包含在搜索中而引起混淆。我没有在示例中执行此操作,但只是确认这不是我关注的元素。

谢谢你的帮助。

(已编辑,以在示例数据中添加带有标点符号的单词示例。)

ger*_*sht 6

您可以创建一个reactive元素,而不是依赖于数据表的搜索功能,该元素首先按输入进行过滤,然后将匹配的单词替换为嵌入在<span style="background-color:yellow;">标签中的相同单词。这应该允许通过更复杂的正则表达式获得更大的搜索灵活性。

您需要添加escape = Ftodatatable以便正确解释 HTML 标记。我已添加options = list(dom = "lt")todatatable以删除数据表的搜索字段并将注意力集中在左侧搜索字段上。

过滤条件相当模糊,以防止表格消失,直到找到完美匹配——即,当您键入“o”时,表格不应该消失,因为没有完美匹配,然后在“on”处重新出现。如果匹配的话被发现,亮点则仅出现即onOnon.,但不stonescone等这里是什么样子的一瞥:

在此处输入图片说明

这是代码。请注意,我使用 dplyr 的过滤和变异函数,因为它们可以通过它们的*_all变体轻松应用于多个列:

library(shiny)
library(DT)
library(data.table)
library(dplyr) # For `filter_all` and `mutate_all`.

example_data <- iris
    # data.table(words = c("on", "scone", "wrong", "stone"), 
    #                        description = c("The word on", "Scone is not on.", "Not on either", "Not here at all"))

ui = shinyUI(fluidPage(

    sidebarLayout(
        sidebarPanel(
            textInput("word_select", label = "Word to search")
        ),
        mainPanel(
            dataTableOutput("word_searched")
        )
    )
))

server = shinyServer(function(input, output, session) {

    # This is your reactive element.
    df_reactive <- reactive({
            example_data %>%
                # Filter if input is anywhere, even in other words.
                filter_all(any_vars(grepl(input$word_select, ., T, T))) %>% 
                # Replace complete words with same in HTML.
                mutate_all(~ gsub(
                              paste(c("\\b(", input$word_select, ")\\b"), collapse = ""),
                              "<span style='background-color:yellow;'>\\1</span>",
                              .,
                              TRUE,
                              TRUE
                              )
                          )
    })

    # Render your reactive element here.
    output$word_searched <- renderDataTable({
        datatable(df_reactive(), escape = F, options = list(dom = "lt"))
    })

})

shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)