猎犬匹配不适用于特殊字符

Posted

技术标签:

【中文标题】猎犬匹配不适用于特殊字符【英文标题】:Bloodhound matching not working with special characters 【发布时间】:2020-08-05 10:09:09 【问题描述】:

我正在使用 typeahead.js 和 Bloodhound 来使用本地来源搜索用户:

let users = [
  name: 'John Doe (john.doe@email.org)', value: '3421',
  name: 'Jane Doe (test@email.org)', value: '8100',
];

匹配和显示key是name:

$('input').typeahead(
  
    minLength: 1,
    highlight: true
  ,
  
    name: 'users',
    displayKey: 'name',
    source: new Bloodhound(
      datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
      queryTokenizer: Bloodhound.tokenizers.whitespace,
      local: users
    )
  
);

在按用户名搜索时匹配,例如“约翰”或“简”。但如果您通过电子邮件搜索,例如“john.doe”、“test”或“email.org”。

但是,如果括号被删除,例如'John Doe john.doe@email.org' 然后 "john.doe" 匹配。但不是“email.org”。

其他特殊字符,如<,例如'John Doe <john.doe@email.org>' 有同样的问题。

为什么特殊字符会破坏数据匹配,我可以做些什么来帮助它?

这是working pen。

我可以有一个额外的属性:

let users = [
  name: 'John Doe (john.doe@email.org)', value: '3421', match: 'John Doe john.doe@email.org',
  name: 'Jane Doe (test@email.org)', value: '8100', match: 'Jane Doe test@email.org',
];

并通过新键匹配:

datumTokenizer: Bloodhound.tokenizers.obj.whitespace('match')

或者我可以拥有一个新属性 email 并拥有以下数据标记器:

datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email])

但这远非理想。但是我怎样才能使 name 键匹配?

【问题讨论】:

【参考方案1】:

看来你需要使用自己的分词器,像这样。

const customTokenizer = (user) => 
  const tokens = user.name.split(/[\s()]+/);
  console.info('Tokenizer', user, '=>', tokens);
  return tokens;
;

let users = [
    name: 'John Doe (john.doe@email.org)',
    value: '3421'
    // , email: 'john.doe@email.org'
  ,
  
    name: 'Jane Doe (test@email.org)',
    value: '8100'
    //, email: 'test@email.org'
  ,
];

$('input').typeahead(
  minLength: 1,
  highlight: true
, 
  name: 'users',
  displayKey: 'name',
  source: new Bloodhound(
    // datumTokenizer: u => Bloodhound.tokenizers.whitespace([u.name + ' ' + u.email]),
    datumTokenizer: customTokenizer,
    queryTokenizer: Bloodhound.tokenizers.whitespace,
    local: users
  )
);
.tt-menu 
  background-color: white;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"></script>

<div id="search">
  <input type="text" placeholder="Search user">
</div>

【讨论】:

【参考方案2】:

为您的datumTokenizerqueryTokenizer 使用nonword 标记器。

【讨论】:

以上是关于猎犬匹配不适用于特殊字符的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate 函数 lower 和 upper 不适用于波兰语特殊字符

正则表达式验证规则,以避免特殊字符不适用于 laravel 中的文本字段

AIX 脚本中的 sed 不适用于特殊字符 [重复]

基本身份验证用户名中的特殊字符不适用于 Chrome,但适用于 IE 和 Firefox

RegEx 用于匹配除一些特殊字符和“:)”之外的所有字符

Javascript RegExp 用于精确匹配具有特殊字符的多个单词