思路:首先获取输入框的值,并使用字符串方法trim将其两端空格去除得到inputValue,由于输入中可能本身包含正则表达式特殊含义字符,故需要使用双重转义将其转换为普通含义。此处构建一个特殊字符数组regKey,并遍历inputValue,判断当前元素是否在regKey中,如果在则在其前面加上\\,再在每个元素后面加上.*?,表示两个字符之间可以贪婪匹配任意内容,然后使用处理好的字符串创建正则表达式reg。如果inputValue不为空,则使用filter方法过滤所有满足reg的元素(使用reg.test(item)方法判断是否满足)并得到过滤后的数组matches,如果matches的长度大于0,则清空原始的ul内容,再遍历matches并为每个元素创建对应的li再加入到ul中并显示,反之则隐藏。
<div class="search"> <div><input type="text" class="js-input" value="的"></div> <div class="js-suggest"> <ul> <li>根据输入框的值</li> <li>从给定字符串数组中筛选出匹配的数据,依次显示在li节点中</li> <li>如果没有匹配的数据,请移除所有li节点,并隐藏.js-suggest节点</li> </ul> </div> </div> <script type="text/javascript"> function suggest(items) { var input = document.querySelector('.js-input'); var suggestContainer = document.querySelector('.js-suggest'); var ul = suggestContainer.querySelector('ul'); var inputValue = input.value.trim(); let reg = ''; //手写特殊字符处理输入数据 const regKey = ['(', ')', '.', '?', '^', '/', '\\', '*', '[', ']', '|', '+', '{', '}', '$']; for (i of inputValue) { if (regKey.includes(i)) { // 其中\\是将不含正则含义的字符双中=重转义为元字符 i = '\\' + i; } // .*?表示在两个字符串中匹配任意数量字符 reg += i +'.*?'; } // console.log(reg); reg = new RegExp(reg); var matches = []; ul.innerHTML = ''; if (inputValue !== '') { matches = items.filter(function(item) { return reg.test(item); }); } if (matches.length > 0) { matches.forEach(function(match) { var li = document.createElement('li'); li.textContent = match; ul.appendChild(li); }); suggestContainer.classList.remove('hide'); } else { suggestContainer.classList.add('hide'); } } suggest(['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '10', '110']) </script>
总结:regex有两种创建方法,一种是字面量方法,一种是构造函数方法。注意,字面量方法中没有正则含义的元字符是使用转义,即一个反斜杠,而构造函数方法中没有正则含义的元字符是使用双重转义,即两个反斜杠。
// 字面量方法: var expression = / pattern / flags 没有正则含义的元字符都必须转义,正则表达式中的元字符包括: ( [ { \ ^ $ | ) ? * + .]} 标志flag的含义: g :表示全局(global)模式,即模式将被应用于所有字符串,而非在发现第一个匹配项时立即停止; i :表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写; m :表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹配的项; // 构造函数方法: var expression = new RegExp("pattern ", "flags") 没有正则含义的元字符(或组合字符)要对字符进行双重转义