Regex to Match Symbols: !$%^&*()_+|~-=`{}[]:";'<>?,./

I'm trying to create a Regex test in JavaScript that will test a string to contain any of these characters:

!$%^&*()_+|~-=`{}[]:";'<>?,./

More Info If You're Interested :)

It's for a pretty cool password change application I'm working on. In case you're interested here's the rest of the code.

I have a table that lists password requirements and as end-users types the new password, it will test an array of Regexes and place a checkmark in the corresponding table row if it... checks out :) I just need to add this one in place of the 4th item in the validation array.

var validate = function(password){
valid = true;


var validation = [
RegExp(/[a-z]/).test(password), RegExp(/[A-Z]/).test(password), RegExp(/\d/).test(password),
RegExp(/\W|_/).test(password), !RegExp(/\s/).test(password), !RegExp("12345678").test(password),
!RegExp($('#txtUsername').val()).test(password), !RegExp("cisco").test(password),
!RegExp(/([a-z]|[0-9])\1\1\1/).test(password), (password.length > 7)
]


$.each(validation, function(i){
if(this)
$('.form table tr').eq(i+1).attr('class', 'check');
else{
$('.form table tr').eq(i+1).attr('class', '');
valid = false
}
});


return(valid);


}

Yes, there's also corresponding server-side validation!

415877 次浏览

这个问题的正则表达式非常简单。只要使用字符类。连字符是字符类中的一个特殊字符,因此它需要放在第一位:

/[-!$%^&*()_+|~=`{}\[\]:";'<>?,.\/]/

还需要转义其他正则表达式元字符。

编辑: 连字符是特殊的,因为它可以用来表示一个字符范围。这个相同的字符类可以通过范围简化为:

/[$-/:-?{-~!"^_`\[\]]/

有三个范围。“ $”到“/”,“ :”到“ ?”以及“{”到“ ~”。最后一个字符串不能更简单地用一个范围来表示: !”^ _‘[]。

使用 ACSII table查找字符类的范围。

实现这一目标的最简单、最快捷的方法是:

/[^\p{L}\d\s@#]/u

解释

匹配下面列表中没有出现的单个字符

  • \p{L} = > 匹配来自任何语言的任何类型的字母

  • \d = > 匹配数字0到9

  • \s => matches any kind of invisible character

  • @# = > @#字符

不要忘记传递 u(unicode)标志。

// The string must contain at least one special character, escaping reserved RegEx characters to avoid conflict
const hasSpecial = password => {
const specialReg = new RegExp(
'^(?=.*[!@#$%^&*"\\[\\]\\{\\}<>/\\(\\)=\\\\\\-_´+`~\\:;,\\.€\\|])',
);
return specialReg.test(password);
};

实现这一点的一个简单方法是负集[ ^ w s ]:

  • 任何不是字母数字字符(字母和数字)的东西
  • 任何不是空格、制表符或换行符(统称为空格)的东西

由于某些原因,[ W S ]不以相同的方式工作,它不做任何过滤。Zael 对其中一个答案的评论提供了一些解释。

回答我

/[\W\S_]/

Explanation

这将创建一个字符类,删除单词字符、空格字符,并重新添加下划线字符(因为下划线是“ word”字符)。剩下的就是特殊字符了。大写字母表示其小写对应字母的否定。

\W将选择所有相当于 [^a-zA-Z0-9_]的非“单词”字符
\S将选择所有等效于 [ \t\n\r\f\v]的非“空格”字符
_将选择“ _”,因为我们在使用 \W时否定它,并且需要将它添加回来

(?=\W_)(?=\S).呢?它检查与 .匹配的字符不是单词字符(但是允许使用 _) ,也不是空格。

Note: as @Casimir et Hippolyte pointed out in another comment, this will also match characters like é and such. If you don't expect such characters then this is a working solution.

以@jeff-hillman 的回答为基础,这是完整的版本

/[\\@#$-/:-?{-~!"^_`\[\]]/

测试

function noSpecialChars(str) {
const match = str.match(/[\\@#$-/:-?{-~!"^_`\[\]]/)
if (!match) return
  

throw new Error("got unsupported characters: " + match[0])
}


// prettier-ignore
const symbols = ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", ".", ":", ";", "|","~","`","{","}","[","]","\"","'","<",">","?","/", "\\"]


symbols.forEach((s) => {
it(`validates no symbol ${s}`, async () => {
expect(() => {
noSpecialChars(s)
}).toThrow();
})
})