简体   繁体   English

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

[英]Bloodhound matching not working with special characters

I am using typeahead.js with Bloodhound to search users using a local source:我正在使用带有 Bloodhound 的 typeahead.js 来使用本地源搜索用户:

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

The matching and display key is name :匹配和显示键是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
    })
  }
);

It does match when searching by the user's name, eg "John" or "Jane".当按用户名搜索时,它确实匹配,例如“John”或“Jane”。 But not if you search by email, eg "john.doe", "test" or "email.org".但如果您按 email 搜索,例如“john.doe”、“test”或“email.org”,则不会。

However, if the parentheses are removed, eg 'John Doe john.doe@email.org' then "john.doe" does match.但是,如果括号被删除,例如'John Doe john.doe@email.org'那么“john.doe”确实匹配。 Not "email.org" though.但不是“email.org”。

Other special characters like < , eg 'John Doe <john.doe@email.org>' has the same issue.其他特殊字符如< ,例如'John Doe <john.doe@email.org>'也有同样的问题。

Why are special characters disrupting the datum matching and what can I do to help it?为什么特殊字符会破坏数据匹配,我能做些什么来帮助它?

Here is an working pen .这是一支工作笔

I can have an extra attribute:我可以有一个额外的属性:

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'},
];

And match by the new key:并通过新键匹配:

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

Or I can have a new property email and have the following datum tokenizer:或者我可以拥有一个新属性email并拥有以下基准标记器:

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

But that's far from ideal.但这远非理想。 But how can I just make the name key match?但是我怎样才能使name键匹配?

It seems that you need to use own tokenizer, like this.看来您需要像这样使用自己的标记器。

 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>

use the nonword tokenizer for both your datumTokenizer and queryTokenizer .datumTokenizerqueryTokenizer使用nonword词标记器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM