正则表达式为某些字符提供错误

时间:2016-02-21 23:23:02

标签: javascript regex

我遇到this pen at codePen,发现了一个错误。如果您在搜索框中输入以下字符:

  

),(,[,+,\,*,?

我收到以下错误(我分别输入了每个字符):

enter image description here

我认为问题出在正则表达式部分。第19行:

var rgx = new RegExp(this.value, "i");

为什么会发生这种情况,我该如何解决?

CodePen



document.addEventListener("DOMContentLoaded", function() {
  "use strict"
  var style = "" + "<style>" + ".filter .hidden {" + "opacity: 0;" + "}" +
    ".filter > * {" + "position: absolute;" +
    "transition: .5s ease-in-out;" + "}" + "</style>";
  document.head.insertAdjacentHTML("beforeend", style);

  var list = document.querySelectorAll(".filter > *");
  var h = list[0].offsetHeight,
    arr = [],
    i = -1,
    l = list.length;
  var anim = "transform" in document.body.style ? "transform" : "webkitTransform";

  while (++i < l) {
    arr.push(list[i].textContent.trim());
    list[i].style[anim] = "translateY(" + i * h + "px)";
  }

  document.querySelector("input.filter").addEventListener("input", function() {
    var rgx = new RegExp(this.value, "i");
    arr.forEach(function(el, idx) {
      if (rgx.test(el)) list[idx].classList.remove("hidden");
      else list[idx].classList.add("hidden");
      var i = -1;
      var p = 0;
      while (++i < l) {
        if (list[i].className != "hidden")
          list[i].style[anim] = "translateY(" + p++ * h + "px)";
      }
    })
  })
})
&#13;
@import url(https://fonts.googleapis.com/css?family=Titillium+Web);
 html {
  height: 100%;
}
body {
  width: 100%;
  height: 100%;
  display: -webkit-box;
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -webkit-justify-content: center;
  -ms-flex-pack: center;
  justify-content: center;
  margin: 0;
  font: 14px'Titillium Web', sans-serif;
  letter-spacing: 2px;
  background: -webkit-linear-gradient(320deg, #543958 0%, #a06060 25%, #bea27b 50%, #9ca898 75%, #506d8d 100%) no-repeat center center fixed;
  background: linear-gradient(130deg, #543958 0%, #a06060 25%, #bea27b 50%, #9ca898 75%, #506d8d 100%) no-repeat center center fixed;
}
section {
  -webkit-align-self: top;
  -ms-flex-item-align: top;
  align-self: top;
  margin: 150px 0;
  display: block;
  position: relative;
  width: 380px;
  max-height: 550px;
  color: rgba(244, 230, 254, 0.7);
  background: rgba(199, 131, 252, 0.05);
  border-top: 15px solid rgba(0, 0, 0, 0.15);
  border-bottom: 40px solid rgba(0, 0, 0, 0.06);
  -webkit-filter: drop-shadow(26px 26px 20px rgba(0, 0, 0, 0.5));
  filter: drop-shadow(26px 26px 20px rgba(0, 0, 0, 0.5));
  box-shadow: -4vh -6vh 16vh -6vh rgba(0, 0, 0, 0.2), -4vh 6vh 16vh -6vh rgba(0, 0, 0, 0.15);
}
section header {
  padding: 1em 1.4em;
  background: rgba(0, 0, 0, 0.12);
  margin: 0 auto 0 auto;
}
section header h4 {
  height: 3rem;
  margin: 0 0 1rem 0;
  padding: 0;
  line-height: 1.1rem;
  text-align: center;
  border-radius: 3px;
  font-size: 1.1rem;
}
section header h4 span {
  padding: 1.2rem;
}
section header h4 span.c {
  padding: .5rem;
  background: rgba(0, 0, 0, 0.045);
  border-bottom: 2px solid rgba(233, 205, 254, 0.8);
}
section header input[type="search"] {
  margin: 0 .5rem;
  padding: .5rem;
  width: 95%;
  color: rgba(244, 230, 254, 0.8);
  background: transparent;
  border: none;
  border-bottom: 1px solid rgba(210, 158, 250, 0.5);
  font-size: 1.15rem;
  -webkit-transition: translateX 6s ease-in;
  transition: translateX 6s ease-in;
}
section header input[type="search"]:focus {
  outline: none;
  border: 1px solid rgba(210, 158, 250, 0.5);
}
section header input[type="search"]:focus::-webkit-input-placeholder {
  -webkit-transform: translateX(70%);
  transform: translateX(70%);
  opacity: 0;
}
section header input[type="search"]:focus::-webkit-input-placeholder:-moz-placeholder {
  -webkit-transform: translateX(70%);
  transform: translateX(70%);
  opacity: 0;
}
section header input[type="search"]:focus::-webkit-input-placeholder::-moz-placeholder {
  -webkit-transform: translateX(70%);
  transform: translateX(70%);
  opacity: 0;
}
section header input[type="search"]:focus::-webkit-input-placeholder:-ms-input-placeholder {
  -webkit-transform: translateX(70%);
  transform: translateX(70%);
  opacity: 0;
}
section header input[type="search"]:focus::-webkit-input-placeholder::-ms-input-placeholder {
  -webkit-transform: translateX(70%);
  transform: translateX(70%);
  opacity: 0;
}
section header input[type="search"]::-webkit-input-placeholder {
  color: rgba(233, 205, 254, 0.8);
  -webkit-transition: ease-in 0.3s;
  transition: ease-in 0.3s;
  -webkit-transform-origin: 0 50%;
  transform-origin: 0 50%;
}
section header input[type="search"]:-moz-placeholder {
  color: rgba(233, 205, 254, 0.8);
  -webkit-transition: ease-in 0.3s;
  transition: ease-in 0.3s;
  transform-origin: 0 50%;
}
section header input[type="search"]::-moz-placeholder {
  color: rgba(233, 205, 254, 0.8);
  -webkit-transition: ease-in 0.3s;
  transition: ease-in 0.3s;
  transform-origin: 0 50%;
}
section header input[type="search"]:-ms-input-placeholder {
  color: rgba(233, 205, 254, 0.8);
  -webkit-transition: ease-in 0.3s;
  transition: ease-in 0.3s;
  transform-origin: 0 50%;
}
section header input[type="search"]::-ms-input-placeholder {
  color: rgba(233, 205, 254, 0.8);
  -webkit-transition: ease-in 0.3s;
  transition: ease-in 0.3s;
  transform-origin: 0 50%;
}
section .filter {
  padding: 1rem 0;
}
section .filter li {
  width: 100%;
  padding: 1rem 0;
  line-height: 1.5rem;
  -webkit-filter: drop-shadow(26px 26px 20px rgba(0, 0, 0, 0.7));
  filter: drop-shadow(26px 26px 20px rgba(0, 0, 0, 0.7));
  list-style-type: none;
  text-align: left;
}
section .filter li span {
  font-size: 1.15rem;
  padding: 1.8rem;
}
section .filter li:nth-child(odd) {
  background: rgba(255, 255, 255, 0.03);
  margin: 0;
}
&#13;
<section>
  <header>
    <h4>
      <span>Log</span>
      <span>Favorites</span>
      <span class ='c'>Contacts</span>
  </h4>
    <input type='search' placeholder=" Search" autofocus class="filter">
  </header>
  <ul class="filter">
    <li><span class='img'></span><span class='name'>John</span>  <span class='ph'>609-579-1254</span>
    </li>
    <li><span class='img'></span><span class='name'>Diane</span>  <span class='ph'>908-240-2297</span>
    </li>
    <li><span class='img'></span><span class='name'>Mike</span>  <span class='ph'>303-539-1425</span>
    </li>
    <li><span class='img'></span><span class='name'>Mary</span>  <span class='ph'>424-308-9976</span>
    </li>
    <li><span class='img'></span><span class='name'>Adam</span>  <span class='ph'>509-998-0025</span>
    </li>
    <li><span class='img'></span><span class='name'>Billy</span>  <span class='ph'>609-898-3325</span>
    </li>
  </ul>
</section>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

这个问题的答案需要熟悉正则表达式。来自http://www.regular-expressions.info

  

正则表达式(regex或简称regexp)是用于描述搜索模式的特殊文本字符串。您可以将正则表达式视为类固醇上的通配符。您可能熟悉通配符,例如* .txt,以查找文件管理器中的所有文本文件。正则表达式等价于。* \ .txt $。

正则表达式使用各种特殊字符组合在一起,所有特殊字符都有不同的含义。正如您所发现的那样,导致搜索框中断的字符在正则表达式中被视为特殊字符。例如,()用于表示正则表达式中的字符“组”。

简要回答“如何修复”的问题:简单的方法是在\中的任何特殊字符前添加this.value\是一个特殊字符,它会使紧跟其后的字符被视为“非特殊”字符。

e.g。

var escapedValue = this.value.replace(")", "\\)");
escapedValue = escapedValue.replace("(", "\\(");
escapedValue = escapedValue.replace("[", "\\[");
escapedValue = escapedValue.replace("+", "\\+");
escapedValue = escapedValue.replace("\\", "\\\\)");
escapedValue = escapedValue.replace("*", "\\*");
escapedValue = escapedValue.replace("?", "\\?");
var rgx = new RegExp(escapedValue, "i");

请注意,此代码段不能完全解决问题(特殊字符列表并非详尽无遗),并且它不是一个非常优雅的解决方案,但它说明了一般概念。

答案 1 :(得分:1)

这可能是替换所有metachars以使其成为文字的好方法。

\n

更新

看了你的codepen链接后,我看到你没有实例化 正则表达式正确对象。

参数如下:text_escaped = text.replace(/([.^$|*+?()\[\]{}\\-])/g, "\\$1");
我相信你错了。
你的RegExp( string, flags )
应该是var rgx = new RegExp(this.value, text_escaped);

以下是一些关于JavaScript正则表达式的有用链接:

Regex Reference的

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions http://www.w3schools.com/jsref/jsref_obj_regexp.asp

从那里它显示了如何定义自己的函数来转义元字符。

  

转义用户输入以将其视为文字字符串   在正则表达式中可以通过简单的替换来完成:

var rgx = new RegExp(text_escaped);

然后用例就像:

function escapeRegExp(string){
  return string.replace(/([.*+?^${}()|[\]\\])/g, "\\$1"); // $1 means capture group 1
}