问题 JavaScript过滤类似的字符串


上下文:我正在使用HTML表提供大型列表的前端。该表的内容有各种不同的(印欧语系)语言。我想让我的用户轻松过滤表格。

实现“查找类似”搜索的简单/最简单的方法是什么? “找到类似”我的意思是:

  • 忽略任何puncation(例如,发现 h-ell.o 在寻找时 hello
  • 忽略同形体(例如,发现 hélló 在寻找时 hello
  • ......可能更多,反之亦然。

我已经有了JQuery,但是,如果合适的话,还会安装第三方JS库。

例子:

[ 'hello', 'héllo', 'h-ello', 'hallo', 'hellot', 'hell', 'hellø' ]

用户搜索 héllo,应该匹配 [ 'héllo', 'hello', 'h-ello', 'hellø'] 不应该匹配 'hallo' (仅拼写,a与e)完全“连接”。舒尔德不匹配 hellot (太长)。不应该匹配 hell (太短)。


6846
2017-10-08 23:45


起源

尝试进行一个简单的搜索,如果一个人设法正确地用普通/欧洲语言获得“大部分”单词,它就会显示它。基本上我想说你应该玩字符串长度,如果你有3或更高的匹配,它应该返回结果。由于大多数欧洲语言都有类似的辅音。 - ZombieChowder
我想这可能是另一种解决方案,但是,我更喜欢另一种解决方案。不管怎样,谢谢! - D.R.
google.com/search?q=levenshtein+javascript - Reeno
Levenshtein是克服拼写错误的合适解决方案。不是我想要的。我想我的问题的解决方案会以某种方式使用角色 en.wikipedia.org/wiki/Unicode_character_property 比较字符串的属性。 - D.R.
您正在“寻找一个简单的库解决方案”,但“要求我们推荐或查找书籍,工具,软件库,教程或其他场外资源的问题都是Stack Overflow的主题”* - noppa


答案:


你想要什么可以在步骤中描述

  • 从搜索到的字符串中删除变音符号,这是完成的 这个答案
  • 从搜索到的字符串中删除非字母数字字符,完成后 这个答案
  • 比较搜索到的字符串和用户输入,可选择忽略大小写

完整的代码如下。你需要的功能是 searchOccurences

var defaultDiacriticsRemovalMap = [{
  'base': 'A',
  'letters': '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F'
}, {
  'base': 'AA',
  'letters': '\uA732'
}, {
  'base': 'AE',
  'letters': '\u00C6\u01FC\u01E2'
}, {
  'base': 'AO',
  'letters': '\uA734'
}, {
  'base': 'AU',
  'letters': '\uA736'
}, {
  'base': 'AV',
  'letters': '\uA738\uA73A'
}, {
  'base': 'AY',
  'letters': '\uA73C'
}, {
  'base': 'B',
  'letters': '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181'
}, {
  'base': 'C',
  'letters': '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E'
}, {
  'base': 'D',
  'letters': '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779'
}, {
  'base': 'DZ',
  'letters': '\u01F1\u01C4'
}, {
  'base': 'Dz',
  'letters': '\u01F2\u01C5'
}, {
  'base': 'E',
  'letters': '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E'
}, {
  'base': 'F',
  'letters': '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B'
}, {
  'base': 'G',
  'letters': '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E'
}, {
  'base': 'H',
  'letters': '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D'
}, {
  'base': 'I',
  'letters': '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197'
}, {
  'base': 'J',
  'letters': '\u004A\u24BF\uFF2A\u0134\u0248'
}, {
  'base': 'K',
  'letters': '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2'
}, {
  'base': 'L',
  'letters': '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780'
}, {
  'base': 'LJ',
  'letters': '\u01C7'
}, {
  'base': 'Lj',
  'letters': '\u01C8'
}, {
  'base': 'M',
  'letters': '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C'
}, {
  'base': 'N',
  'letters': '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4'
}, {
  'base': 'NJ',
  'letters': '\u01CA'
}, {
  'base': 'Nj',
  'letters': '\u01CB'
}, {
  'base': 'O',
  'letters': '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C'
}, {
  'base': 'OI',
  'letters': '\u01A2'
}, {
  'base': 'OO',
  'letters': '\uA74E'
}, {
  'base': 'OU',
  'letters': '\u0222'
}, {
  'base': 'OE',
  'letters': '\u008C\u0152'
}, {
  'base': 'oe',
  'letters': '\u009C\u0153'
}, {
  'base': 'P',
  'letters': '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754'
}, {
  'base': 'Q',
  'letters': '\u0051\u24C6\uFF31\uA756\uA758\u024A'
}, {
  'base': 'R',
  'letters': '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782'
}, {
  'base': 'S',
  'letters': '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784'
}, {
  'base': 'T',
  'letters': '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786'
}, {
  'base': 'TZ',
  'letters': '\uA728'
}, {
  'base': 'U',
  'letters': '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244'
}, {
  'base': 'V',
  'letters': '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245'
}, {
  'base': 'VY',
  'letters': '\uA760'
}, {
  'base': 'W',
  'letters': '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72'
}, {
  'base': 'X',
  'letters': '\u0058\u24CD\uFF38\u1E8A\u1E8C'
}, {
  'base': 'Y',
  'letters': '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE'
}, {
  'base': 'Z',
  'letters': '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762'
}, {
  'base': 'a',
  'letters': '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250'
}, {
  'base': 'aa',
  'letters': '\uA733'
}, {
  'base': 'ae',
  'letters': '\u00E6\u01FD\u01E3'
}, {
  'base': 'ao',
  'letters': '\uA735'
}, {
  'base': 'au',
  'letters': '\uA737'
}, {
  'base': 'av',
  'letters': '\uA739\uA73B'
}, {
  'base': 'ay',
  'letters': '\uA73D'
}, {
  'base': 'b',
  'letters': '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253'
}, {
  'base': 'c',
  'letters': '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184'
}, {
  'base': 'd',
  'letters': '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A'
}, {
  'base': 'dz',
  'letters': '\u01F3\u01C6'
}, {
  'base': 'e',
  'letters': '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD'
}, {
  'base': 'f',
  'letters': '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C'
}, {
  'base': 'g',
  'letters': '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F'
}, {
  'base': 'h',
  'letters': '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265'
}, {
  'base': 'hv',
  'letters': '\u0195'
}, {
  'base': 'i',
  'letters': '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131'
}, {
  'base': 'j',
  'letters': '\u006A\u24D9\uFF4A\u0135\u01F0\u0249'
}, {
  'base': 'k',
  'letters': '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3'
}, {
  'base': 'l',
  'letters': '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747'
}, {
  'base': 'lj',
  'letters': '\u01C9'
}, {
  'base': 'm',
  'letters': '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F'
}, {
  'base': 'n',
  'letters': '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5'
}, {
  'base': 'nj',
  'letters': '\u01CC'
}, {
  'base': 'o',
  'letters': '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275'
}, {
  'base': 'oi',
  'letters': '\u01A3'
}, {
  'base': 'ou',
  'letters': '\u0223'
}, {
  'base': 'oo',
  'letters': '\uA74F'
}, {
  'base': 'p',
  'letters': '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755'
}, {
  'base': 'q',
  'letters': '\u0071\u24E0\uFF51\u024B\uA757\uA759'
}, {
  'base': 'r',
  'letters': '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783'
}, {
  'base': 's',
  'letters': '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B'
}, {
  'base': 't',
  'letters': '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787'
}, {
  'base': 'tz',
  'letters': '\uA729'
}, {
  'base': 'u',
  'letters': '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289'
}, {
  'base': 'v',
  'letters': '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C'
}, {
  'base': 'vy',
  'letters': '\uA761'
}, {
  'base': 'w',
  'letters': '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73'
}, {
  'base': 'x',
  'letters': '\u0078\u24E7\uFF58\u1E8B\u1E8D'
}, {
  'base': 'y',
  'letters': '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF'
}, {
  'base': 'z',
  'letters': '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763'
}];

var diacriticsMap = {};
for (var i = 0; i < defaultDiacriticsRemovalMap.length; i++) {
  var letters = defaultDiacriticsRemovalMap[i].letters;
  for (var j = 0; j < letters.length; j++) {
    diacriticsMap[letters[j]] = defaultDiacriticsRemovalMap[i].base;
  }
}

// "what?" version ... http://jsperf.com/diacritics/12
function removeDiacritics(str) {
  return str.replace(/[^\u0000-\u007E]/g, function(a) {
    return diacriticsMap[a] || a;
  });
}

function removeNonAlphanumeric(str) {
  return str.replace(/[^0-9a-z]/gi, '');
}

function searchOccurences(hay, needle, ignoreCase) {
  needle = removeNonAlphanumeric(removeDiacritics(needle));
  if (ignoreCase) needle = needle.toUpperCase();
  return hay.filter(
    function(word) {
      word = removeNonAlphanumeric(removeDiacritics(word));
      if (ignoreCase) word = word.toUpperCase();
      return word == needle;
    })
}




// Below is the demonstration


var words = "L'avantage d'utiliser le lorem ipsum est bien     évidemment de pouvoir créer des maquettes ou de remplir un site internet de contenus qui présentent un rendu s'approchant un maximum du rendu final. \n Par défaut lorem ipsum ne contient pas d'accent ni de caractères spéciaux contrairement à la langue française qui en contient beaucoup. C'est sur ce critère que nous proposons une solution avec cet outil qui générant du faux-texte lorem ipsum mais avec en plus, des caractères spéciaux tel que les accents ou certains symboles utiles pour la langue française. \n L'utilisation du lorem standard est facile d’utilisation mais lorsque le futur client utilisera votre logiciel il se peut que certains caractères spéciaux ou qu'un accent ne soient pas codés correctement. \n Cette page a pour but donc de pouvoir perdre le moins de temps possible et donc de tester directement si tous les encodages de base de donnée ou des sites sont les bons de plus il permet de récuperer un code css avec le texte formaté !".split(' ');

console.log(searchOccurences(words, "francaise"));

当然了 defaultDiacriticsRemovalMap 可能不完整。要解决这个问题,您需要深入了解Unicode的工作原理。

替代方法去除变音符号 

Unicode具有称为规范化形式的东西。用一个例子来说明这个角色 ş 只包含一个字符代码 351 在NFC(标准化表格C,Javascript和HTML默认使用此我认为)。但在NFD中,它由2个字符组成 s 和 Combining Cedilla 由char代码表示 115 和 807。因此,您只需将字符串转换为NFD并删除定义的字母范围内的任何字符即可实现目标。

幸运的是,EcmaScript 6引入了一个 规范化功能。旧浏览器本身不支持它,但我认为它可以 polyfill'ed。这是您使用规范化形式实现删除变音符号的方法:

function removeNonAlphanumericAndDiacritics(str) {
  return str.normalize("NFD").replace(/[^0-9a-z]/gi, '');
}

function searchOccurences(hay, needle, ignoreCase) {
  needle = removeNonAlphanumericAndDiacritics(needle);
  if (ignoreCase) needle = needle.toUpperCase();
  return hay.filter(
    function(word) {
      word = removeNonAlphanumericAndDiacritics(word);
      if (ignoreCase) word = word.toUpperCase();
      return word == needle;
    })
}


// Below is the demonstration

var words = "L'avantage d'utiliser le lorem ipsum est bien     évidemment de pouvoir créer des maquettes ou de remplir un site internet de contenus qui présentent un rendu s'approchant un maximum du rendu final. \n Par défaut lorem ipsum ne contient pas d'accent ni de caractères spéciaux contrairement à la langue française qui en contient beaucoup. C'est sur ce critère que nous proposons une solution avec cet outil qui générant du faux-texte lorem ipsum mais avec en plus, des caractères spéciaux tel que les accents ou certains symboles utiles pour la langue française. \n L'utilisation du lorem standard est facile d’utilisation mais lorsque le futur client utilisera votre logiciel il se peut que certains caractères spéciaux ou qu'un accent ne soient pas codés correctement. \n Cette page a pour but donc de pouvoir perdre le moins de temps possible et donc de tester directement si tous les encodages de base de donnée ou des sites sont les bons de plus il permet de récuperer un code css avec le texte formaté !".split(' ');

console.log(searchOccurences(words, "francaise", true));


6
2017-10-12 04:59



谢谢,我喜欢。你知道怎么判断 defaultDiacriticsRemovalMap 是 完成?是否有某种Unicode属性说“嘿,我实际上是字符xyz只是添加了变音符号”? - D.R.
@ D.R。我不能确定它是否完整。因此,我用另一种方式扩展了答案,肯定是一个更好的方法。 - Gökhan Kurt
听起来像是一个 声音 理念!太好了,我会尽快试一试! - D.R.
这是一些严肃的东西,但很棒。你可能永远不会发现这种级别的搜索,最强大的文本编辑器,但JavaScript可以做到这一点。印象最深刻。 - Alexander Dixon
@GokhanKurt,现在我知道这是超级顶级但也可以用于常规搜索词。我有一个快速脚本库,我保存在autohotkey中。这个宝石有一个位置,但我想确保它不会太臃肿的任务。让我知道。 - Alexander Dixon


这就是你需要的

https://github.com/codebox/homoglyph/blob/master/javascript/src/homoglyph.js

要扩展功能,请使用此文件,其中包含同名字符 https://github.com/codebox/homoglyph/blob/master/raw_data/chars.txt

我想你正在使用jquery脚本进行表搜索。使用上面的脚本扩展功能以识别同形字符。

用于处理标点符号
如果脚本是一个常见的插件,它必须循​​环遍历表,匹配每个单元格的单词。当选择单元格的值(内容)时,使用类似下面的代码来忽略该单元格值的标点符号。

s.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"");

然后将修改后的单元格值和用户输入的值传递给同形函数。修改homoglyph函数以返回true或false而不是匹配,并将boolean传递给当前的插件搜索函数,只是表示单元格是否具有匹配的内容。

如果很难修改现有代码,请参阅此示例, http://www.vijayjoshi.org/examples/filterTable.html  并使用homoglyph函数扩展它并忽略标点符号。


4
2017-10-11 15:19



谢谢,想把你的答案和@GökhanKurt的答案结合起来! - D.R.


某种模糊搜索库似乎是您正在寻找的:

来自维基百科:

在计算机科学中,近似字符串匹配(通常俗称为模糊字符串搜索)是一种寻找与模式近似(而非精确)匹配的字符串的技术。

fusejs.io 是一个例子(第一个谷歌结果)


1
2017-10-11 13:30



我会以此为准。 fuse.js是一个非常好的库。我创建了一个快速 的jsfiddle 你可以看看。它确实包括拼写错误 hallo,所以你可能想要运行它,然后第二次过滤结果,提取任何不属于拼写错误的结果。 - leigero


您需要做的就是实现一个规范化函数,对于每个等效字符串,它返回相同的结果(无论语法是否正确)并使用它来比较两个字符串。

例:

"use strict";

var str_norm = (function(){

    const accents = [
        // First charcter is "master" the rest equivalences.
        // (Add as much equivalences as you need)
        'aàáäâ',
        'eèéëê',
        'iìíïî',
        'oòóöôø',
        'uùúüû',
    ].map(function(p){
        return {
            re: new RegExp('['+p.substring(1)+']', 'g'),
            chr: p.substring(0,1),
        };
    });

    function removeAccents(str) {
        for (var i=0; i<accents.length; i++) {
            str = str.replace(accents[i].re, accents[i].chr);
        };
        return str;
    };

    return function str_norm(str) {

        return removeAccents(str
            .normalize() // Replace "a"+"á" (etc...) UTF-8 sequence by its "a" (etc...) single character equivalence.
            .toLowerCase() // Normalyze to lowercase.
        )
            .replace(/[^a-z0-9\s.,:;ñç]/g, '') // Remove all strange characters.
            .replace(/[\s.,:;]+/g, ' ') // Replace spaces and punctuation (notice: previously accepted) sequences with single space.
        ;


    };
})();


console.log (str_norm("H-éllò  ;- Wø%rld!!")); // hello world
console.log (str_norm("H-éllò  ;- Wø%rld!!") == str_norm("Hello World!!!!!!")); // true

对于部分匹配,你需要更多的管道。例如,匹配包含提供的模式的字符串。

var str = "H-éllò  ;- Wø%rld!!";
var searchPattern = "world";
//console.log (str_norm(str) == str_norm(searchPattern)); // (boolean) false
//console.log (str_norm(str).match(str_norm(searchPattern))); // (array with matches) (true value).
console.log (!!str_norm(str).match(str_norm(searchPattern))); // (boolean) true (coerced by "!!").
var searchPattern2 = "foo";
//console.log (str_norm(str).match(str_norm(searchPattern2))); // null (falsy)
console.log (!! str_norm(str).match(str_norm(searchPattern2))); // (boolean) false

// Actual output:
// true
// false

...或者也使用典型的wilcards(但这需要稍微改变规范化函数,添加一个参数来指示它不删除wilcard字符):

"use strict";

var str_norm = (function(){//{{{

    [...] (No changes here)

    return function str_norm(str, acceptWilcards) {

        str = removeAccents(str
            .normalize() // Replace "a"+"á" with "a", etc...
            .toLowerCase() // Normalyze to lowercase.
        )
            .replace(/[^a-z0-9\s.,:;ñç*?]/g, '') // Remove all strange characters.
        ;
        if (! acceptWilcards) str = str.replace(/[*?]/g, ''); // Also remove wilcards.

        str = str.replace(/[\s.,:;]+/g, ' '); // Replace spaces and punctuation sequences with single space.

        return str;

    };
})();//}}}


var str = "H-éllò beautïfull ;- Wø%rld!!";
var searchPattern = "hello*world";

var searchRegex = new RegExp(str_norm(searchPattern, true)
    .replace(/\?/g, '.') 
    .replace(/\*/g, '.*')
);      

console.log (!!str_norm(str).match(searchRegex)); // true

注意: 礼貌点, searchRegex 施工还需要更换'。'和'*'by'。'和'*'分别用于逃避文字出现并在其他替换中使用lookbehind。但是,在我们的例子中,我们之前在规范化函数中过滤它,因为我们不接受它。所以我们不需要为此烦恼。


0
2017-10-18 07:50