我有一个数据表,通过使用searchStringToRegexString函数将搜索字符串翻译为regex表达,我在其中建立了自定义的搜索逻辑(使用AND和OR).然后将以下搜索字符串转换为:

'term1 AND term2' => (?=.*term1)(?=.*term2) 

'term1 OR term2' => (?=.*term1)|(?=.*term2) 

'term1 term2' => (?=.*term1 term2)

'term1 term2 OR term3 AND term4' => (?=.*term1 term2)|(?=.*term3)(?=.*term4)

虽然自定义搜索按照列搜索的预期运行,但我在全局搜索中遇到了以下问题:

(A.)全球搜索"福特或狗"效果良好.然而,"ma AND cat"显示零结果,这是不正确的.

(B.)此外,当切换到列搜索时,例如,到列"宠物",并输入搜索"cat",显示的全局搜索字符串从"ma AND cat"更改为"(?=.* ma)(?=.*cat )".

为了解决这个问题,我解除了分配的事件处理程序.然而,全局搜索似乎没有正确解释regex字符串.

如果有人可以给我一些关于如何解决全局搜索的regex搜索的建议.

enter image description here

library(DT)
library(shiny)


ui = fluidPage(
   shiny::tags$script("
      function searchStringToRegexString(search_str) {
         let term_before = false;
         let regex_str = '(?=.*';
         let parts = search_str.trim().split(' ');  // array with terms split by spaces
         for (let part of parts) {
            if ((part === 'AND') || (part === 'OR')) {
               regex_str += (part === 'AND') ? ')(?=.*' : ')|(?=.*';  // 'term1 AND term2' => (?=.*term1)(?=.*term2), 'term1 OR term2' => (?=.*term1)|(?=.*term2)
               term_before = false;
            } else {
               regex_str += (term_before === true) ? (' ' + part) : part;  // 'term1 term2' => (?=.*term1 term2)
               term_before = true;
            }
         }
         regex_str += ')';
         regex_str = regex_str.replace('|(?=.*)', '').replace('(?=.*)', '');  // remove empty ANDs and ORs
         console.log('search_str:', search_str, ', regex_str:', regex_str);
         return regex_str;
      }
   "),
   fluidRow(
      column(width = 12,
             DTOutput("dtable")
      )
   )
)


server = function(input, output, session) {
   data = data.frame(
      car = c("Mazda", "Mazda RX4", "Mazda RX4 Wag", "Ford", "Mercedes"),
      pet = c("dog", "dog", "cat", "cat", "cat")
   )

   output$dtable = renderDT({
      datatable(
         data,
         filter = list(position = "top", clear = TRUE, plain = FALSE),
         options = list(
            searchDelay = 1500,
            dom = "ft",
            columnDefs = list(list(targets = "_all", className = "dt-center")),
            fixedHeader = FALSE,
            initComplete = JS("
               function(settings) {
                  let glo_search_handler = $('.dataTables_filter input');
                  let instance = settings.oInstance;
                  let col_search_handler = instance.parent().find('.form-group input');
                  let table = instance.api();

                  col_search_handler.unbind();  // unbind the default datatable search handlers
                  glo_search_handler.unbind();

                  glo_search_handler.on('keyup.globalSearch', function(e) {  // global search handler
                     e.preventDefault(); // prevent the default form submit behavior
                     let glo_search_str = $(this).val().trim();
                     if (glo_search_str === '') {
                        table.search('').draw();
                     } else {
                        let glo_regex_str = searchStringToRegexString(glo_search_str);
                        table.search(glo_regex_str, true, false, true).draw();  // search term, regex, smart, caseInsensitive
                     }
                  });

                  col_search_handler.on('keyup.columnSearch', function(e) {  // custom column search handler
                     e.preventDefault(); // prevent the default form submit behavior
                     let col_search_str = $(this).val().trim();
                     let index = 1 + col_search_handler.index(this);
                     let column = table.column(index);
                     if (col_search_str === '') {
                        column.search('').draw();
                     } else {
                        let col_regex_str = searchStringToRegexString(col_search_str);
                        column.search(col_regex_str, true, false, true).draw();
                     }
                  });
               }
            ")
         )
      )
   }, server = TRUE)
}

shinyApp(ui = ui, server = server)

推荐答案

虽然当您将"and"字符串翻译为(?=.*term1)(?=.*term2)时,它会产生技术上正确的regex,但它不适用于服务器端DT搜索的实现.然而,如果您启用了smart搜索(在您的示例中是自动)并在括号之间插入一个空白,那么它就会起作用:

(?=.*term1) (?=.*term2)

更改global搜索字符串的另一个问题与draw()有关,可以通过暂时保存该值并在draw()之后重新分配它来避免:

let currentGlobalSearchString = $('.dataTables_filter input').val();
column.search(col_regex_str, true, false, true).draw();
$('.dataTables_filter input').val(currentGlobalSearchString);

enter image description here

Javascript相关问答推荐

try 在addEventHandler内设置表单的文件输入.值=空

Promise.all立即跳到那时,而不是调用所有Promise

Express.js:以块形式发送响应

如何从defineExpose访问数据和方法

Next.js Next/Image图像隐含性有任何类型-如何修复?

如何修复内容安全策略指令脚本-SRC自身错误?

在分区内迭代分区

对象和数字减法会抵消浏览器js中的数字

Regex结果包含额外的match/group,只带一个返回

在使用HighChats时如何避免Datatables重新初始化错误?

如何通过将实例方法的名称传递给具有正确类型的参数的继承方法来调用实例方法?

我可以使用空手道用户界面来获取网页的当前滚动位置吗?

不能将空字符串传递给cy.containes()

try 使用javascript隐藏下拉 Select

为什么我的自定义元素没有被垃圾回收?

如何利用CSS中的隐藏元素实现平滑扩展和防止网格行间隙

AJAX POST在控制器中返回空(ASP.NET MVC)

try 将Redux工具包与MUI ToggleButtonGroup组件一起使用时出错

不协调嵌入图片

表单数据中未定义的数组键